Проблемы с поднятием ошибки валидации в форме Django
Я пытаюсь проверить, что отправленный 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 ответа
Канал Django в IRC спас меня здесь. Проблема заключалась в том, что URLField.clean() делает две вещи, которые я не ожидал:
- Если схема URL отсутствует (например, http://), метод добавляет префикс http: // к URL.
- метод также добавляет завершающий слеш.
Результаты возвращаются и сохраняются в форме 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')
Я делаю это так. Это немного проще.
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
Я думаю, вы можете вернуть '' и заполнить _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
Хорошо, я вошел в систему, потому что нашел это через Google с похожей проблемой и хотел добавить комментарий к сообщению Карла Мейерса, отмечая, что использование self._errors полностью допустимо в соответствии с Django docs: