Bastian, spiego a voi il mio codice di template, spero che aiuta a voi:
Dal django 1.2 it is able to write validation code on model. Quando lavoriamo con modelforms, instance.full_clean() viene chiamato sulla convalida del modulo.
In ogni modello ho sovrascrivere clean()
metodo con una funzione personalizzata (questo metodo viene chiamato automaticamente da full_clean() sulla convalida 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()
Poi nel rules.py
file scrivere regole di bussiness. Inoltre mi collego al mio pre_save()
funzione personalizzata per prevenire salvare un modello con stato errato:
da issues.models importazione Problema
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
Poi, ModelForm chiama metodo pulito del modello e il mio custon controllo del funzionamento di uno stato diritto o genera un errore gestito dal modulo del modello.
Al fine di mostrare gli errori di forma, si dovrebbe includere questo sul modello di modulo:
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
{{error}}
{% endfor %}
{% endif %}
La ragione è che erros validazione del modello ara binded per errore non_field_errors voce di dizionario.
Quando si salva o si elimina un modello di una forma si dovrebbe ricordare che un errore può essere sollevato:
try:
issue.delete()
except ValidationError, e:
import itertools
errors = list(itertools.chain(*e.message_dict.values()))
Inoltre, è possibile aggiungere gli errori a un dizionario modulo non 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 )
Ricordare che questo codice non viene eseguito sul metodo save(): si noti che full_clean() non verrà chiamato automaticamente quando si chiama il metodo save() del modello, né come risultato della convalida ModelForm.Quindi, è possibile aggiungere gli errori a un dizionario modulo a non 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 )
Hai ragione mi trasferirò la mia convalida in la forma, è molto più facile. Mi è piaciuta l'idea di avere tutto nel modello. – Bastian
@bastian, mi è piaciuto anche avere tutto nel modello. È facile dimenticare una regola aziendale quando si scrive un nuovo modulo, ma non se le regole aziendali sono nel modello. Per questo motivo ho spostato le convalide dai moduli al modello, come ho spiegato nel mio post. Sono aperto a conoscere nuovi metodi per farlo in un modo più elegante se esiste. In ogni caso evito di scrivere codice di convalida sui moduli. – danihp
Va bene mettere la validazione nel tuo modello usando i validatori o scrivendo un metodo 'clean()'. Tutto quello che stavo dicendo è che il metodo 'save()' non è il posto giusto. Dai un'occhiata ai documenti su [validating objects] (https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects). – Alasdair