我有模特
@with_author
class Lease(CommonInfo):
version = IntegerVersionField( )
is_renewed = models.BooleanField(default=False)
unit = models.ForeignKey(Unit)
is_terminated = models.BooleanField(default=False)
def __unicode__(self):
return u'%s %i %s ' % ("lease#", self.id, self.unit)
def clean(self):
model = self.__class__
if self.unit and (self.is_active == True) and model.objects.filter(unit=self.unit, is_terminated = False , is_active = True).count() == 1:
raise ValidationError('Unit has active lease already, Terminate existing one prior to creation of new one or create a not active lease '.format(self.unit))
我有一张表格
class LeaseForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(LeaseForm, self).__init__(*args, **kwargs)
self.fields['unit'].required = True
class Meta:
model = Lease
fields = [ 'unit',
'is_active','is_renewed', 'description']
并且每次保存此表单而不选择我正在获取的单位的值
错误RelatedObjectDoesNotExist
来自模型中的clean函数,因为没有self.unit
但是我明确地验证了单位字段。(至少我相信)
我做错了什么?
答案 0 :(得分:1)
请注意,调用时不会自动调用full_clean() 你的模型的save()方法。你需要手动调用它 想要为您自己手动创建的一步模型验证运行 楷模。 [docs]
这显然是出于向后兼容性原因,请检查this票证。
模型的full_clean()
方法负责调用Model.clean()
,但因为它从未被调用过,所以基本上省略了模型内的清理方法。
你可以为此做几件事。您可以手动调用模型的清洁。或者,您可以使用其干净方法将验证逻辑移动到 ModelForm 。如果您主要通过表单创建实例,我认为这是执行验证的最佳位置(以及更常见的练习)。
试试这个:
class LeaseForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(LeaseForm, self).__init__(*args, **kwargs)
self.fields['unit'].required = True
# IF your validation logic includes multiple fields override this
def clean(self):
cleaned_data = super(LeaseForm, self).clean()
# .. your logic
return cleaned_data
# IF just your field's value is enough for validation override this
def clean__unit(self):
data = self.cleaned_data.get('unit', None)
# .. your logic
return data
class Meta:
model = Lease
fields = [ 'unit',
'is_active','is_renewed', 'description']