我已经定义了一个模型并定制了clean()方法以便更好地验证。如果我在前端使用模型,它可以工作,我无法保存不符合我的验证标准的模型。 但是当我通过shell保存或编写我的测试时,仍会保存错误的模型。
models.py
class FooModel(models.Model):
weight_min = models.DecimalField(default=40.0, max_digits=4, decimal_places=1)
weight_max = models.DecimalField(default=40.0, max_digits=4, decimal_places=1)
def clean(self):
if self.weight_min > self.weight_max:
raise ValidationError("'Weight min' must be smaller than 'Weight max'.")
tests.py
def test_create_model_with_wrong_weight(self):
foo = FooModel(weight_min=40.0, weight_max=30.0)
self.assertRaises(ValidationError, match.save()) # Works, but still saves the model
self.assertIs(0, Match.objects.all()) # Fails, QuerySet has objects.
我阅读了docs并尝试在save()中调用full_clean(),但后来我不知道如何编写测试。
我该怎么做:
答案 0 :(得分:4)
save
方法不应该进行验证,它没有按设计进行,因此您甚至可以保存无效的模型实例。
您的工作流程如下所示:
try:
match.full_clean()
match.save()
except ValidationError as e:
# Do something based on the errors contained in e.message_dict.
# Display them to a user, or handle them programmatically.
https://docs.djangoproject.com/en/2.0/ref/models/instances/#validating-objects
向模型的.save()方法添加验证(即.full_clean()调用)通常不是一个好主意,因为如果稍后您将通过表单使用此模型,则.full_clean()将被调用两次(通过表单,通过.save()方法),但如果你不介意,你可以像下面这样做:
class Match:
...
def save(self, *args, **kwargs):
try:
self.full_clean()
super().save(*args, **kwargs) # actually save the valid match
except ValidationError as e:
... # work with e.message_dict etc.