Note that full_clean() will not be called automatically when you call your model’s save() method, nor as a result of ModelForm validation.
For this reason, I alltimes call clean() model method before save model. I invoke this call trhough pre_save signal.
For more business rules issolation, I write all them in a separate python module: rules.py.
This is models.py ---------------------------------------------------------------
from django.db import models
class Issue(models.Model):
....
def clean(self): |
rules.Issue_clean(self) |
from issues import rules |
rules.connect() |
This is rules.py ---------------------------------------------------------------
from issues.models import Issue
def connect(): |
from django.db.models.signals import post_save, pre_save, pre_delete |
#issues |
pre_delete.connect(Issue_pre_delete, sender= Incidencia) |
pre_save.connect(Issue_pre_save, sender = Incidencia ) |
post_save.connect(Issue_post_save, sender = Incidencia ) |
def Incidencia_clean( instance ): |
import datetime as dt |
errors = {} |
#dia i hora sempre informats |
if not instance.dia_incidencia: |
errors.setdefault('dia_incidencia',[]).append(u'Falten Dades: Cal dia i franja') |
#dia i hora sempre informats |
if not instance.franja_incidencia: |
errors.setdefault('franja_incidencia',[]).append(u'Falten Dades: Cal dia i franja') |
#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'''No es poden posar o modificar incidències amb més d' una setmana)''') |
#No incidències al futur. |
if instance.getDate() > datetime.now(): |
errors.setdefault('dia_incidencia 2',[]).append(u'''Encara no pots posar incidències en aquesta classe. Encara no s'ha realitzat.''') |
#No incidencies alumne que és baixa: |
if instance.alumne.data_baixa is not None and instance.alumne.data_baixa < instance.dia_incidencia: |
errors.setdefault('dia_incidencia 3',[]).append(u'''L'alumne estava de baixa en aquesta data.''') |
if len( errors ) > 0: |
raise ValidationError(errors) |
def Issue_pre_save(sender, instance, **kwargs): |
instance.clean() |
In order to show errors on form, you should include this on form template:
{% if form.non_field_errors %} |
{% for error in form.non_field_errors %} |
{{error}} |
{% endfor %} |
{% endif %} |
When you save or delete a model out of a form:
try: issue.delete() except ValidationError, e: import itertools errors = list( itertools.chain( *e.message_dict.values() ) )
To add errors to a form dictionary on 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 )
You can see samples on ghap project source code.
Here some samples:
Cap comentari:
Publica un comentari a l'entrada