Django: переопределение метода clean () в формах - вопрос об ошибках - PullRequest
9 голосов
/ 22 января 2010

Я делал такие вещи в чистом методе:

if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
      raise forms.ValidationError('The type and organization do not match.')
if self.cleaned_data['start'] > self.cleaned_data['end']:
      raise forms.ValidationError('The start date cannot be later than the end date.')

Но тогда это означает, что форма может вызвать только одну из этих ошибок одновременно. Есть ли способ для формы вызвать обе эти ошибки?

РЕДАКТИРОВАТЬ # 1 : Любые решения для вышеупомянутых хороши, но хотели бы что-то, что также работало бы в сценарии как:

if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
      raise forms.ValidationError('The type and organization do not match.')
if self.cleaned_data['start'] > self.cleaned_data['end']:
      raise forms.ValidationError('The start date cannot be later than the end date.')
super(FooAddForm, self).clean()

Где FooAddForm является ModelForm и имеет уникальные ограничения, которые также могут вызывать ошибки. Если кто-нибудь знает что-то подобное, это было бы здорово ...

Ответы [ 4 ]

18 голосов
/ 22 января 2010

Из документов:

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

from django.forms.util import ErrorList

def clean(self):

  if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
    msg = 'The type and organization do not match.'
    self._errors['type'] = ErrorList([msg])
    del self.cleaned_data['type']

  if self.cleaned_data['start'] > self.cleaned_data['end']:
    msg = 'The start date cannot be later than the end date.'
    self._errors['start'] = ErrorList([msg])
    del self.cleaned_data['start']

  return self.cleaned_data
7 голосов
/ 22 января 2010
errors = []
if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
      errors.append('The type and organization do not match.')
if self.cleaned_data['start'] > self.cleaned_data['end']:
     errors.append('The start date cannot be later than the end date.')

if errors:
    raise forms.ValidationError(errors)
3 голосов
/ 02 февраля 2018

Хотя это старый пост, если вы хотите меньше кода, вы можете использовать add_error() метод для добавления сообщений об ошибках. Я расширяю ответ @ kemar, чтобы показать использованный случай:

add_error() автоматически удаляет поле из словаря cleaned_data, вам не нужно удалять его вручную. Также вам не нужно ничего импортировать, чтобы использовать это.

документация здесь

def clean(self):

  if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
    msg = 'The type and organization do not match.'
    self.add_error('type', msg)

  if self.cleaned_data['start'] > self.cleaned_data['end']:
    msg = 'The start date cannot be later than the end date.'
    self.add_error('start', msg)

  return self.cleaned_data
3 голосов
/ 09 марта 2010

Если вы предпочитаете, чтобы сообщения об ошибках были прикреплены к форме, а не к конкретным полям, вы можете использовать ключ "__all__" следующим образом:

msg = 'The type and organization do not match.'
self._errors['__all__'] = ErrorList([msg])

Кроме того, как объясняют в документации Django: «если вы хотите добавить новую ошибку в определенное поле, вам следует проверить, существует ли ключ в self._errors или нет. Если нет, создайте новую запись для данного ключ, содержащий пустой экземпляр * 1006. * В любом случае вы можете добавить свое сообщение об ошибке в список для имени поля, о котором идет речь, и оно будет отображаться при отображении формы. "

...