这是我正在研究的模型的一个非常简化的版本:
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
方法,但我不确定这是否是实现这一目标的最明智的方法。
有人有任何建议吗?
答案 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
,业务规则从表单验证中消失。