Проблемы с поднятием ошибки валидации в форме Django - PullRequest
5 голосов
/ 04 декабря 2008

Я пытаюсь проверить, что отправленный 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, которые уже существуют в базе данных. Есть идеи?

Ответы [ 4 ]

4 голосов
/ 04 декабря 2008

Канал Django в IRC спас меня здесь. Проблема заключалась в том, что 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')
1 голос
/ 04 декабря 2008

Я делаю это так. Это немного проще.

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
0 голосов
/ 15 ноября 2010

Хорошо, я вошел в систему, потому что нашел это через Google с похожей проблемой и хотел добавить комментарий к сообщению Карла Мейерса, отмечая, что использование self._errors полностью допустимо в соответствии с Django docs:

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

0 голосов
/ 04 декабря 2008

Я думаю, вы можете вернуть '' и заполнить _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
...