Django 模型验证
Posted
技术标签:
【中文标题】Django 模型验证【英文标题】:Django model validation 【发布时间】:2017-08-16 02:49:04 【问题描述】:我遇到了验证问题。 我需要同时使用表单验证和模型验证,但是django(1.10)似乎不喜欢这样。
这是我的设置的简短版本:
class MyModel(models.Model):
fk = models.ForeignKey('ap.Model')
foo = models.CharField(max_length=12)
def clean(self):
if self.fk.som_field != self.foo:
raise ValidationError("This did not validate")
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ('fk',)
def view(request):
instance = MyModel(foo='bar')
form = MyModelForm(data=request.POST, instance=instance)
if form.is_valid():
# process
# redirect
# display template
所以我在模型本身中有一些模型字段验证。 我在这里需要这个,因为它在我的应用程序的其他非表单相关部分中重复使用。
我在表单中有一些用户输入验证。 在这种情况下,检查提供的 fk 是否有效且存在。
但是当表单被验证并且用户提供的“fk”无效时,表单被拒绝。 但表单还调用 MyModel.full_clean 添加更多模型验证。
问题是在字段 fk 中没有任何数据的情况下调用 MyModel.clean() 将引发 RelatedObjectDoesNotExist 异常。
我怎样才能以正确的方式做到这一点? 我觉得 MyModel.full_clean() 不应该被表单调用,直到表单本身有效,以确保模型通过至少正确的字段类型进行验证。
我可以将 MyModel.clean 操作嵌入到 try/except 中,这会捕获 RealtedObjectDoesNotExist,但它对我来说具有不好的代码味道。 MyModel.fk 存在这一事实应通过第一个表单层验证来确保。
【问题讨论】:
【参考方案1】:如您所见,无论表单是否有效,模型表单都会执行实例验证(通过调用 self.instance.full_clean()`)。
您可以阻止这种行为(我可能会尝试覆盖 _post_clean
,但我认为考虑 clean
方法中的行为会更简单。
与其捕获异常,不如在访问self.fk
之前检查self.fk_id
不是None 会更简单。
class MyModel(models.Model):
fk = models.ForeignKey('ap.Model')
foo = models.CharField(max_length=12)
def clean(self):
if self.fk_id is not None and self.fk.som_field != self.foo:
raise ValidationError("This did not validate")
【讨论】:
以上是关于Django 模型验证的主要内容,如果未能解决你的问题,请参考以下文章