Django: проблемы с проверкой полей URL при переопределении проверки формы

#django #django-forms

#django #django-forms

Вопрос:

У меня есть некоторая форма с двумя полями URL, оба не обязательны. Форма используется для установки значения JSONField в модели из этих двух полей url (для удобства пользователя), все работает нормально. Если пользователь вводит что-либо, кроме URL, в url1 или url2, django выдает ошибку проверки в форме «Введите действительный URL».

Теперь я хочу заставить пользователя вводить URL в ЛЮБОЕ из этих полей URL. Для этого я переопределяю метод clean:

 class MyForm(forms.ModelForm):
    url1 = forms.URLField(required=False)
    url2 = forms.URLField(required=False)

    def clean(self):
        cleaned_data = super(MyForm, self).clean()
        if not cleaned_data['url1'] and not cleaned_data['url2']:
            raise ValidationError(
                _("You should enter at least one URL"),
                code='no_urls'
            )
        return cleaned_data
  

Это работает, но есть проблема: если пользователь вводит некоторые данные «не URL» в url1 или url2 и отправляет форму, Django выдает KeyError со значением исключения: ‘url1’ (или ‘url2’) вместо отображения ошибки проверки в форме

Что не так? Спасибо!

Ответ №1:

Как задокументировано в довольно многих местах — в частности, в части о перекрестной проверке -, cleaned_data содержит только допустимые данные — поля, которые не были проверены, здесь не отображаются. Вы должны учитывать это так или иначе — проверяя наличие ключа или, как показано во фрагменте примера перекрестной проверки, используя dict.get() :

 def clean(self):
    cleaned_data = super(MyForm, self).clean()
    # boolean algebra 101: "not A and not B" => "not (A or B)"
    if not (cleaned_data.get('url1') or cleaned_data.get('url2')):
        raise ValidationError(
            _("You should enter at least one URL"),
            code='no_urls'
        )
    return cleaned_data
  

Комментарии:

1. Спасибо, Бруно! Понял, теперь все в порядке. LOL @ algebra 101, действительно )))