简体   繁体   English

Django Model 字段中的 If 语句

[英]If statement in Django Model Fields

I want to add these fields to my Store Model, but i wanna include logic that if Let's say WooCoomerce was chosen as a StoreType, i want Access_Token not to be Required.我想将这些字段添加到我的商店 Model,但我想包含这样的逻辑,如果我们说 WooCoomerce 被选为 StoreType,我希望 Access_Token 不是必需的。 Also when i Choose either Shopify/Shopper i want Consumer_key and Consumer_secret not to be required.此外,当我选择 Shopify/Shopper 时,我希望不需要 Consumer_key 和 Consumer_secret。 Do you have any idea how to get around that?你知道如何解决这个问题吗?

    StoreType = models.CharField(blank=True, choices=Storetypes.choices, max_length=12)
    Api_Url = models.CharField(blank=True)
    Access_Key = models.CharField(blank=True, max_length=100)
    Consumer_Key = models.CharField(blank=True, max_length=100)
    Consumer_Secret = models.CharField(blank=True, max_length=100)

You can't make this type of logic on database layer.您不能在数据库层上制作这种类型的逻辑。 For this case you can move this logic to a classmathod of the model to satisfy the dry-pattern.对于这种情况,您可以将此逻辑移至 model 的类方法以满足干模式。 Also set the fields to nullable in your model.还要在 model 中将字段设置为可为空。

Something like so:像这样:

class YourClass(models.Model):
    store_type = models.CharField(blank=True, choices=Storetypes.choices, max_length=12)
    api_url = models.CharField(blank=True,)
    access_key = models.CharField(blank=True, max_length=100, null=True)
    consumer_key = models.CharField(blank=True, max_length=100, null=True)
    consumer_secret = models.CharField(blank=True, max_length=100, null=True)

    @classmethod
    def save_woo_commerce(cls, api_url, consumer_key, consumer_secret):
        return YourClass.objects.create(
            store_type="woo_commerce",
            api_url=api_url,
            consumer_key=consumer_key,
            consumer_secret=consumer_secret
        )

    @classmethod
    def save_shopify(cls, api_url, access_key):
        return YourClass.objects.create(
            store_type="shopify",
            access_key=access_key,
            api_url=api_url,
        )

With that your logic is still connected to the model and you can reuse instance creation on multiple places of your code.这样,您的逻辑仍然连接到 model,您可以在代码的多个位置重用实例创建。

At some point those fields are going to be inputs.在某些时候,这些字段将成为输入。

If they come in through a form, it's a matter of using a clean method that generates errors for invalid combinations, or checking at the view level.如果它们通过表单进入,则需要使用一种clean的方法来为无效组合生成错误,或者在视图级别进行检查。 A pattern I have found myself using quite often with class-based views (based on FormView) is like the following.我发现自己经常与基于类的视图(基于 FormView)一起使用的模式如下所示。 Key points: form.add_error to convert a valid form into an invalid one, and return self.form_invalid(form) to show the user what needs to be fixed.要点: form.add_error将有效表单转换为无效表单,并return self.form_invalid(form)向用户显示需要修复的内容。

def form_valid( self, form)
    store_type = form.Cleaned_data['store_type']
    api_url = form.cleaned_data[' ... ']
    ...
    # now, further checks
    ...
    errors = False
    if store_type == SHOPIFY or store_type == SHOPPER:
         # consumer_key and consumer secret not required
         consumer_key = consumer_secret = ''
         # but presumably, api_url and access_key are mandatory
         if api_url == '':
             # get human representation of store_type
             human_store_type = ...
             form.add_error('api_url', f'API Url is required whenever store type is "{human_store_type}"' ) 
             errors = True
         if access_key == '':
             ... # similar, but add error to access_Key field

         # maybe validate that the api_url and access_key actually work
         # and add an error if they don't work together?
         if not check_valid( api_url, access_key):
             errors = True
             form.add_error( None, 'api_url and access_key do not work with each other') # non-field error

         if errors:
             return self.form_invalid( form)

    elif store_type == ...
        ...

    # OK we have a completely valid set of inputs
    # get the object (if its a ModelForm)
    store  = form.save( commit = False)
    store.api_url = api_url
    ... # and the other fields we extra-validated
    store.save()

    return redirect( ...)

It's possible to subclass the save method on your object to cause an exception if any mandatory fields are blank, but this can be more trouble than its worth.如果任何必填字段为空,则可以对 object 上的save方法进行子类化以导致异常,但这可能比它的价值更麻烦。 If there is one or few views through which these fields can be set, then check there.如果可以通过一个或几个视图设置这些字段,请检查那里。 Sometimes, it's even useful to save an incomplete object: give it a Boolean is_complete field.有时,保存不完整的 object 甚至很有用:给它一个 Boolean is_complete 字段。 For example, it may be necessary for a human supervisor to authorize the addition of a new store.例如,可能需要人工主管授权添加新商店。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM