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)