Bastian, te explico mi código de plantillas, espero que ayuda a que:
Desde django 1.2 it is able to write validation code on model. Cuando trabajamos con modelos, se invoca instance.full_clean() en la validación del formulario.
En cada modelo I sobrescribir clean()
método con una función personalizada (este método es llamado automáticamente de full_clean() en la validación ModelForm):
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 rules.py
archivo que he escribir reglas de negocios. También me conecto a mi pre_save()
función personalizada para evitar guardar un modelo con un estado incorrecto:
de Emisión issues.models importación
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
Entonces, ModelForm llama al método limpio de modelo y mi control de funcionamiento del custon para un estado correcto o genera un error que se maneja por formulario modelo.
Con el fin de mostrar los errores de forma, debe incluir en esta plantilla de formulario:
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
{{error}}
{% endfor %}
{% endif %}
La razón es que los erros de validación del modelo ara binded a un error non_field_errors entrada de diccionario.
Al guardar o borrar un modelo de una forma que usted debe recordar que un error puede ser elevado:
try:
issue.delete()
except ValidationError, e:
import itertools
errors = list(itertools.chain(*e.message_dict.values()))
Además, se puede añadir errores a un diccionario formulario en ningún modelforms:
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.A continuación, puede agregar errores a un diccionario en forma no modelforms:
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 )
Tienes razón voy a mover mi validación en la forma, es mucho más fácil. Me gustó la idea de tener todo en el modelo. – Bastian
@bastian, también me gusta tener todo en el modelo. Es fácil olvidarse de una regla comercial cuando escribe un formulario nuevo, pero no si las reglas comerciales están en el modelo. Por este motivo, he trasladado las validaciones de los formularios al modelo, como explico en mi publicación. Estoy abierto a aprender sobre nuevos métodos para hacer esto de una manera más elegante si existe. En cualquier caso evito escribir código de validación en formularios. – danihp
Está bien poner validación en su modelo utilizando validadores o escribiendo un método 'clean()'. Todo lo que estaba diciendo es que el método 'save()' no es el lugar correcto. Eche un vistazo a los documentos sobre [validación de objetos] (https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects). – Alasdair