我的表格看起来像这样:
class ContactForm(forms.ModelForm):
error_messages = {
'duplicate_name': 'A backup contact with that name already exists for this location',
'missing_location': 'No location supplied.'
}
class Meta:
fields = ('name', 'notification_preference', 'email', 'phone')
model = Contact
········
def clean_name(self):
# FIXME: Location validation shouldn't be happening here, but it's difficult to get
# form fields for foreign key relationships to play nicely with Tastypie
print dir(self)
if 'location' in self.data:
location = Location.objects.get(pk=self.uri_to_pk(self.data['location']))
else:
raise forms.ValidationError(self.error_messages['missing_location'])
# No duplicate names in a given location
if 'name' in self.cleaned_data and Contact.objects.filter(name=self.cleaned_data['name'], location=location).exists():
raise forms.ValidationError(self.error_messages['duplicate_name'])
return self.cleaned_data
我正在使用它来验证对TastyPie API的调用。 clean_name
方法用于防止POST请求发生,如果他们将具有相同名称的联系人发布到同一位置。只要我发出POST请求,这就完美无缺。
如果我创建了一个PATCH,但是更改了已经存在的联系人的电子邮件和电话字段,clean_name
逻辑仍然被触发。由于该名称已存在于给定位置,因此会引发验证错误。
我应该覆盖clean_name
以外的其他内容吗?我可以更改PATCH的工作方式,以便忽略某些验证吗?
答案 0 :(得分:0)
是的,如果您正在检查字段之间的值,我建议您实施一个检查值不会发生冲突的通用def clean(self, data)
。
关于检查重复项,我建议您在.exclude(pk=instance.pk)
查询集中使用exists()
,以防止错误地将模型更新检测为重复项。查看tastypie validation source,它会为正在更新的对象添加适当的self.instance
。
qs = Contact.objects.filter(name=self.cleaned_data.get('name', ''), location=location)
if self.instance and self.instance.pk:
qs = qs.exclude(pk=self.instance.pk)
if qs.exists():
raise forms.ValidationError(...)