我正面临验证问题。 我需要一起使用表单验证和模型验证,但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添加更多的模型验证。
问题是调用MyModel.clean()而字段 fk 中没有任何数据会引发一个RelatedObjectDoesNotExist异常。
我怎样才能以正确的方式做到这一点? 我觉得MyModel.full_clean()不应该被表单调用,直到表单本身有效,以确保模型中至少使用正确的字段类型进行验证。
我可以在try /中嵌入我的MyModel.clean操作,除了会捕获RealtedObjectDoesNotExist,但它对我来说有一个糟糕的代码味道。 MyModel.fk存在的事实应该通过第一次表单层验证来确保。
答案 0 :(得分:0)
如您所见,模型表单执行实例验证(通过调用self.instance.full_clean()`)表单是否有效。
您可以阻止此行为(我可能会尝试覆盖_post_clean
,但我认为考虑clean
方法中的行为更为简单。
在访问self.fk_id
之前,检查self.fk
是否为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")