表单验证 - 干净方法干扰PATCH请求

时间:2013-12-04 21:48:09

标签: python django tastypie

我的表格看起来像这样:

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的工作方式,以便忽略某些验证吗?

1 个答案:

答案 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(...)