当表单不包含所有字段时执行validate_unique

时间:2018-01-25 18:43:49

标签: django django-forms

我最近遇到过我的模型中的validate_unique方法没有运行的情况。这是因为独特测试中涉及的其中一个字段未包含在表单中。在登陆此解决方案之前,我在表单和视图中尝试了很多东西:我首先将字段注入UpdateView的对象,然后在_post_clean中的表单中运行测试。

models.py 

class Link(ModelBase):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=200,blank=True,null=False)
    url = models.URLField(max_length=400,blank=False,null=False)
    profile = models.ForeignKey('Profile',null=False,blank=False,on_delete=models.CASCADE)

    class Meta:
        unique_together = ('url','profile')

    class Admin:
        pass

forms.py 

class LinkForm(ModelForm):

    def _post_clean(self):
        ''' Be sure that the instance validate_unique test 
            is run including the profile field '''
        super(LinkForm,self)._post_clean()
        try:
            self.instance.validate_unique(exclude=None)
        except ValidationError as e:
            self._update_errors(e)

    class Meta:
        model = Link
        fields = ['title','url']

views.py 

class LinkUpdateView(UpdateView):
    model = Link
    form_class = LinkForm

    def get_form_kwargs(self):
        ''' Add profile to self.object before kwargs are populated '''

        if hasattr(self, 'object') and self.object and self.profile:
                self.object.profile = profile

        kwargs = super(LinkUpdateView, self).get_form_kwargs()

        return kwargs   

有没有更好的方法可以做到这一点,而不涉及覆盖内部函数?

1 个答案:

答案 0 :(得分:1)

我有几次类似的问题,我这样解决了:

  • 我在表单中包含了该字段
  • 我在基于班级的视图中覆盖了get_form,将字段隐藏给用户,并为其提供我想要的值。

这样,当包含该字段时,它会触发验证,但用户无法填写它。

看起来像这样:

    def get_form(self, form_class=None):
        form = super(MyClass, self).get_form(form_class)
        form.fields['some_field'].initial = some_value
        form.fields['some_field'].widget = forms.HiddenInput()
        return form