Обработка требований полей модели Django, основанных на других полях - PullRequest
1 голос
/ 27 ноября 2010

Это очень упрощенная версия модели, над которой я работаю:

class ClothingTop(models.Model):

    SWEATER  = 0
    SHIRT    = 1

    TOP_CHOICES = (
        (SWEATER, 'Sweat shirt'),
        (SHIRT, 'Shirt'),
    )

    name = models.CharField(max_length=32)
    type = models.PositiveSmallIntegerField(choices=TOP_CHOICES)
    hoodie = models.BooleanField(default=False)
    buttons = models.PositiveSmallIntegerField(null=True, blank=True)

    def __unicode__(self):
        return self.name

    @property
    def type_text(self):
        if self.type == self.SWEATER:
            if self.hoodie:
                return 'Hooded sweatshirt'
            return 'Plain sweatshirt'
        elif self.type == self.SHIRT:
            return 'Shirt'

Я хочу потребовать buttons, если type установлено на SHIRT.Моей первой мыслью было переопределить метод save, но я не уверен, что это обязательно самый умный способ сделать это.

У кого-нибудь есть какие-либо предложения?

1 Ответ

1 голос
/ 27 ноября 2010

Мое простейшее предложение, и я считаю, что оно лучшее на практике, состоит в том, что вы создаете ClothingTop ModelForm и устанавливаете метод buttons_clean() в форме, которая будет выполнять таможенная проверка. Эта форма также должна быть установлена ​​для ClothingTop ModelAdmin.

Единственный другой способ сделать это - создать настраиваемое поле модели для поля buttons (здесь валидаторы работать не будут, поскольку они получают только значение поля кнопок и не обращают внимания на тип, другие поля модели). Самый простой способ сделать это будет:

ButtonsField(models.PositiveSmallIntegerField):

    def validate(self, value, model_instance):
        # here we get the buttons field value and can get the type value
        # exactly what we need!

        type = getattr(model_instance, 'type')

        if type == SHIRT and not value:
            raise ValidationError('Type set to shirt, but buttons value is empty')

        super(self, ButtonsField).validate(value, model_instance)

Я упомянул подход с настраиваемыми полями для полноты, я думаю, что вам следует пропустить создание настраиваемого типа поля , если он не является полностью универсальным и легко повторно используется в любой модели. , Для этих особых случаев просто используйте проверку формы. Ваши модели должны обеспечивать только целостность базы данных, которую вы уже охватили ClothingTop, бизнес-правила выходят из проверки формы.

...