【问题标题】:Problems raising a ValidationError on a Django Form在 Django 表单上引发 ValidationError 的问题
【发布时间】:2010-09-25 06:14:42
【问题描述】:

我正在尝试验证提交的 URL 是否已存在于数据库中。

Form 类的相关部分如下所示:

from django.contrib.sites.models import Site
class SignUpForm(forms.Form):
    # ... Other fields ...
    url = forms.URLField(label='URL for new site, eg: example.com')

    def clean_url(self):
        url = self.cleaned_data['url']
        try:
            a = Site.objects.get(domain=url)

        except Site.DoesNotExist:
            return url

        else:
            raise forms.ValidationError("That URL is already in the database.  Please submit a unique URL.")

    def clean(self):
        # Other form cleaning stuff.  I don't *think* this is causing the grief

问题是,无论我提交什么值,我都无法提出ValidationError。如果我在clean_url() 方法中做这样的事情:

if Site.objects.get(domain=url):
    raise forms.ValidationError("That URL is already in the database.  Please submit a unique URL.")

然后我得到一个DoesNotExist 错误,即使是数据库中已经存在的 URL。有什么想法吗?

【问题讨论】:

    标签: python django django-forms cleaned-data


    【解决方案1】:

    IRC 中的 django 频道救了我。问题是 URLField.clean() 做了两件我没想到的事情:

    1. 如果不存在 URL 方案(例如 http://),则该方法会在 url 前添加“http://”
    2. 该方法还附加一个斜杠。

    结果返回并存储在表单的cleaned_data 中。所以我检查了cleaned_data['url'],期待example.com,实际上得到http://example.com/。可以说,将我的 clean_url() 方法更改为以下工作:

    def clean_url(self):
            url = self.cleaned_data['url']        
            bits = urlparse(url)
            dom = bits[1]
            try:
                site=Site.objects.get(domain__iexact=dom)
            except Site.DoesNotExist:
                return dom
            raise forms.ValidationError(u'That domain is already taken.  Please choose another')
    

    【讨论】:

      【解决方案2】:

      我是这样做的。稍微简单一点。

      try:
          a = Site.objects.get(domain=url)
          raise forms.ValidationError("That URL is already in the database.  Please submit a unique URL.")
      except Site.DoesNotExist:
          pass
      return url
      

      【讨论】:

      • 那么你还有其他问题。这必须奏效。您是否正在运行“manage.py testserver”并在每次运行时获取一个新的空数据库?你在运行“manage.py runserver”吗?
      • 同意。您的其他验证方法很有可能“引起了悲痛”。
      • 找出问题所在 - URLField.clean() 在cleaned_data 中设置的值与我预期的不同。答案如下。
      【解决方案3】:

      我认为,您可以返回 '' 并填写 _errors。

      msg = u"That URL is already in the database.  Please submit a unique URL."
      self._errors["url"]=ErrorList([msg])
      return ''
      

      from django.contrib.sites.models import Site
      class SignUpForm(forms.Form):
          # ... Other fields ...
      
      url = forms.URLField(label='URL for new site, eg: example.com')
      
      def clean_url(self):
          url = self.cleaned_data['url']
          try:
              a = Site.objects.get(domain=url)
              raise forms.ValidationError("That URL is already in the database.  Please submit a unique URL.")
          except Site.DoesNotExist:
              return url
          return ''
      
      def clean(self):
          # Other form cleaning stuff.  I don't *think* this is causing the grief
      

      【讨论】:

      • -1:引发 ValidationError 是正确的方法。手动填写 self._errors 是没有充分理由的 hack。
      【解决方案4】:

      好吧,我登录了,因为我通过 Google 发现了类似的问题,并想在 Carl Meyers 的帖子中添加评论,指出根据 Django 文档,使用 self._errors 是完全有效的:

      http://docs.djangoproject.com/en/1.2/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-10
        • 1970-01-01
        • 2017-04-04
        • 1970-01-01
        • 1970-01-01
        • 2021-10-02
        • 2021-03-17
        相关资源
        最近更新 更多