python 在 Django 表单上引发 ValidationError 的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/339387/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 19:55:53  来源:igfitidea点击:

Problems raising a ValidationError on a Django Form

pythondjangodjango-formscleaned-data

提问by saturdayplace

I'm trying to validate that a submitted URL doesn't already exist in the database.

我正在尝试验证数据库中不存在提交的 URL。

The relevant parts of the Form class look like this:

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

The problem is, regardless of what value I submit, I can't raise the ValidationError. And if I do something like this in the clean_url()method:

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

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

then I get a DoesNotExisterror, even for URLs that already exist in the Database. Any ideas?

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

采纳答案by saturdayplace

django channel in IRC saved me here. The problem was that the URLField.clean() does two things I wasn't expecting:

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

  1. If no URL scheme is present (eg, http://) the method prepends 'http://' to the url
  2. the method also appends a trailing slash.
  1. 如果不存在 URL 方案(例如,http://),则该方法将“http://”添加到 url
  2. 该方法还附加了一个尾部斜杠。

The results are returned and stored in the form's cleaned_data. So I was checking cleaned_data['url']expecting something like example.comand actually getting http://example.com/. Suffice to say, changing my clean_url()method to the following works:

结果被返回并存储在表单的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')

回答by S.Lott

I do it this way. It's slightly simpler.

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

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

回答by Igorekk

I think, you can return '' and fill _errors.

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

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

or

或者

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

回答by user508418

Well I logged in cause I found this via Google with a similar issue and wanted to add a comment to Carl Meyers post noting that using self._errors is totally valid as per the Django docs:

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

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

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