处理基于其他字段的Django模型字段的要求

时间:2010-11-26 22:32:03

标签: python django django-models

这是我正在研究的模型的一个非常简化的版本:

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 个答案:

答案 0 :(得分:1)

最简单的建议,我相信它是实践中最好的建议,就是您创建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,业务规则从表单验证中消失。