【问题标题】:Passing an argument to the Django ModelForm clean method将参数传递给 Django ModelForm clean 方法
【发布时间】:2025-12-09 22:20:09
【问题描述】:

我正在尝试将参数传递给我的 ModelForm 的 clean 方法,以便我可以对某些数据执行一些额外的验证。

在我的 views.py 文件中,我有:

page_data = page_form.cleaned_data(foo="bar")

在我的 clean_url 方法中,我有:

def clean_url(self, **kwargs):
    url = self.cleaned_data['url']

    if kwargs['foo'] == url:
        query = FlatPage.objects.filter(url=url)
        if query.exists():
            raise forms.ValidationError(("This url is already being used by the '%s' page.") % (query[0].title))

    return url

我不断收到foo 的 KeyError。我不确定我在哪里犯了错误,因为我之前已经传递了 kwarg 变量,但从来没有传递给一个干净的方法。

【问题讨论】:

    标签: django modelform


    【解决方案1】:

    当使用基于类的视图时,您可以使用get_form_kwargs 将变量从视图传递到您的表单,然后再传递给您的清理方法:

    在你看来:

    def get_form_kwargs(self):
        kwargs = super(MyCreateView, self).get_form_kwargs()
        kwargs.update({'url': self.kwargs['url']})  # or wherever the url parameter is coming from
        return kwargs
    

    在您的表单中:

    def __init__(self, *args, **kwargs):
        self.url = kwargs.pop('url', None)
        super(FlatPageForm, self).__init__(*args, **kwargs)
    

    然后在您的clean() 方法中引用self.url

    【讨论】:

      【解决方案2】:

      关键在于通过ModelForm的init方法传递参数:

      def __init__(self, *args, **kwargs):
          self.url = kwargs.pop('url', None)
          super(FlatPageForm, self).__init__(*args, **kwargs)
      

      然后可以通过调用 self.url 在 clean 方法中引用该变量

      def clean_url(self):
          url = self.cleaned_data['url']
          if self.url == url:
               #do something
          else:
               #do something else
      

      【讨论】: