widgets tutorial formularios form fields example avanzados django validation model validationerror

tutorial - Levante un error de validación en el método de guardado de un modelo en Django



formularios django (4)

Bastian, te explico mi código de plantillas, espero que eso te ayude:

Desde django 1.2 es capaz de escribir código de validación en el modelo . Cuando trabajamos con modelos, se invoca instance.full_clean () en la validación del formulario.

En cada modelo, sobrescribo clean() método clean() con una función personalizada (este método se llama automáticamente desde full_clean () en la validación del modelo):

from django.db import models class Issue(models.Model): .... def clean(self): rules.Issue_clean(self) #<-- custom function invocation from issues import rules rules.connect()

Luego en el archivo rules.py escribo reglas de negocios. También conecto pre_save() a mi función personalizada para evitar guardar un modelo con un estado incorrecto:

de issues.models import Issue

def connect(): from django.db.models.signals import post_save, pre_save, pre_delete #issues pre_save.connect(Issue_pre_save, sender = Incidencia ) post_save.connect(Issue_post_save, sender = Incidencia ) pre_delete.connect(Issue_pre_delete, sender= Incidencia) def Incidencia_clean( instance ): #<-- custom function import datetime as dt errors = {} #dia i hora sempre informats if not instance.dia_incidencia: #<-- business rules errors.setdefault(''dia_incidencia'',[]).append(u''Data missing: ...'') #dia i hora sempre informats if not instance.franja_incidencia: errors.setdefault(''franja_incidencia'',[]).append(u''Falten Dades: ...'') #Només es poden posar incidències més ennlà de 7 dies if instance.dia_incidencia < ( dt.date.today() + dt.timedelta( days = -7) ): errors.setdefault(''dia_incidencia 1'',[]).append(u''''''blah blah error desc)'''''') #No incidències al futur. if instance.getDate() > datetime.now(): errors.setdefault(''dia_incidencia 2'',[]).append(u''''''Encara no pots ....'''''') ... if len( errors ) > 0: raise ValidationError(errors) #<-- raising errors def Issue_pre_save(sender, instance, **kwargs): instance.clean() #<-- custom function invocation

Luego, modelform llama al método clean del modelo y mi función custon comprueba si hay un estado correcto o genera un error que se maneja por formulario del modelo.

Para mostrar los errores en el formulario, debe incluir esto en la plantilla de formulario:

{% if form.non_field_errors %} {% for error in form.non_field_errors %} {{error}} {% endfor %} {% endif %}

El motivo es que los errores de validación del modelo están vinculados a la entrada del diccionario de errores non_field_errors.

Cuando guarde o elimine un modelo de un formulario, debe recordar que se puede generar un error:

try: issue.delete() except ValidationError, e: import itertools errors = list( itertools.chain( *e.message_dict.values() ) )

Además, puede agregar errores a un diccionario de formularios sin formas de modelos:

try: #provoco els errors per mostrar-los igualment al formulari. issue.clean() except ValidationError, e: form._errors = {} for _, v in e.message_dict.items(): form._errors.setdefault(NON_FIELD_ERRORS, []).extend( v )

Recuerde que este código no se ejecuta en el método save (): tenga en cuenta que full_clean () no se invocará automáticamente cuando llame al método save () de su modelo ni como resultado de la validación de ModelForm. Luego, puede agregar errores a un diccionario de formularios sin formas de modelos :

try: #provoco els errors per mostrar-los igualment al formulari. issue.clean() except ValidationError, e: form._errors = {} for _, v in e.message_dict.items(): form._errors.setdefault(NON_FIELD_ERRORS, []).extend( v )

No estoy seguro de cómo plantear correctamente un error de validación en el método de guardado de un modelo y devolver un mensaje claro al usuario.

Básicamente, quiero saber cómo debe terminar cada parte del "si", aquella en la que quiero generar el error y la que realmente guarda:

def save(self, *args, **kwargs): if not good_enough_to_be_saved: raise ValidationError else: super(Model, self).save(*args, **kwargs)

Luego quiero saber qué hacer para enviar un error de validación que indique exactamente al usuario qué es lo que falla, como el que Django devuelve automáticamente si, por ejemplo, un valor no es exclusivo. Estoy usando un (ModelForm) y sintonizo todo desde el modelo.


La mayoría de las vistas de Django, por ejemplo, el administrador de Django no podrá manejar un error de validación en el método de guardar, por lo que los usuarios obtendrán 500 errores.

Debería hacer la validación en el formulario del modelo o en el modelo, y subir ValidationError allí. A continuación, llame a save() solo si los datos del formulario modelo son ''lo suficientemente buenos para guardar''.


asegúrese de importar ValidationError también

from django.core.exceptions import ValidationError


def clean(self): raise ValidationError("Validation Error") def save(self, *args, **kwargs): if some condition: #do something here else: self.full_clean() super(ClassName, self).save(*args, **kwargs)