Утверждение If в полях модели Django
Я хочу добавить эти поля в модель моего магазина, но я хочу включить логику, что если, скажем, WooCoomerce был выбран в качестве StoreType, я хочу, чтобы Access_Token не был обязательным. Также, когда я выбираю Shopify/Shopper, я хочу, чтобы Consumer_key и Consumer_secret не были обязательными. Есть ли у вас идеи, как обойти это?
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)
Вы не можете сделать этот тип логики на уровне базы данных. Для этого случая вы можете перенести эту логику в классматод модели, чтобы удовлетворить сухой шаблон. Также установите поля на nullable в вашей модели.
Примерно так:
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,
)
При этом ваша логика все еще связана с моделью, и вы можете повторно использовать создание экземпляра в нескольких местах вашего кода.
В какой-то момент эти поля станут входами.
<<<Если они приходят через форму, то это вопрос использования метода, который генерирует ошибки для недопустимых комбинаций, или проверки на уровне представления. Шаблон, который я довольно часто использую в представлениях на основе классов (основанных на FormView), выглядит следующим образом. Ключевые моменты: clean
преобразовать валидную форму в невалидную, и 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( ...)
Можно подклассифицировать метод save
на вашем объекте, чтобы вызвать исключение, если какие-либо обязательные поля пусты, но это может быть больше проблем, чем пользы. Если есть одно или несколько представлений, через которые можно установить эти поля, проверьте их там. Иногда даже полезно сохранить незавершенный объект: задайте ему поле Boolean is_complete. Например, может потребоваться, чтобы человек-руководитель дал разрешение на добавление нового магазина.