2010-01-22 14 views
9

que he estado haciendo este tipo de cosas en el método de limpieza:Django: Sustitución del método clean() en formas - pregunta sobre la crianza de los errores

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.') 

Pero entonces eso significa que la forma sólo se puede plantear una de estos errores a la vez. ¿Hay alguna manera de que la forma genere ambos errores?

editar # 1: Cualquier solución para lo anterior son grandes, pero le encantaría algo que también funcionaría en un escenario como:

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() 

Dónde FooAddForm es un ModelForm y tiene restricciones únicas que podrían también causa errores. Si alguien sabe de algo así, eso sería genial ...

Respuesta

17

A partir de los documentos:

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 
+0

Esto funciona muy bien (no estaba seguro si me gustaba que los mensajes de error se adjuntasen a los campos en lugar de a la forma completa, pero en realidad es una especie de tiene más sentido de esta manera) y las restricciones únicas de ModelForm también funcionan. Así que estoy aceptando este, ¡gracias! :) –

7
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) 
+0

Grrr .... estaba tratando de dar este +1, pero accidentalmente hice clic dos veces y ahora dice "vote demasiado viejo para ser cambiado" grrr ... De todos modos, buena respuesta :) pero todavía estoy teniendo un problema con eso ... Tengo un método limpio en un ModelForm, donde es importante verificar las restricciones únicas, pero si lo hago: if errors: raise forms.ValidationError (errors) super (CompetitionAddForm, self). clean() entonces son mis errores o los únicos errores de restricción: -/ –

3

Si prefiere que los mensajes de error pueden unir a el formulario en lugar de campos específicos, puede usar la clave "__all__" de esta manera:

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

Además, como explican los documentos de Django: "si desea agregar un nuevo error a un campo en particular, debe verificar si la clave ya existe en self._errors o no. De lo contrario, cree una nueva entrada para la clave dada, sosteniendo una instancia vacía ErrorList. En cualquier caso, puede agregar su mensaje de error a la lista para el nombre de campo en cuestión y se mostrará cuando se muestre el formulario. "

3

Aunque su publicación anterior, si desea menos código, puede usar add_error() . método para agregar mensajes de error que estoy extendiendo la respuesta de la @ de Kemar para mostrar el caso utilizado:.

add_error() elimina automáticamente el campo del diccionario cleaned_data, usted no tiene que eliminar manualmente también usted no tiene que importar nada de usar esto.

documentation is here

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 
Cuestiones relacionadas