巴斯蒂安,我向你解釋我的代碼模板,我希望可以幫助到你:
由於django 1.2 it is able to write validation code on model。當我們使用模型時,instance.full_clean()在表單驗證上被調用。
在每個模型我覆蓋clean()
方法使用自定義功能(該方法將自動從full_clean上的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()
然後在rules.py
文件I寫經營業務規則。此外,我連pre_save()
到我的自定義功能,防止保存錯誤狀態的模型:
從issues.models進口問題
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
然後,調用的ModelForm模型的清潔方法和右狀態我custon功能檢查或引發由模型形式處理的錯誤。
爲了顯示對形式的錯誤,你應該包括這個對錶單模板:
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
{{error}}
{% endfor %}
{% endif %}
的原因是綁定到non_field_errors錯誤辭典條目,模型驗證錯誤回報ARA。
當您保存或刪除模型表單,你應該記住,一個錯誤可能提出:
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 )
:
try:
issue.delete()
except ValidationError, e:
import itertools
errors = list(itertools.chain(*e.message_dict.values()))
此外,您還可以在沒有modelforms到表單字典添加錯誤
請記住,此代碼不在save()方法上執行:請注意,調用模型的save()方法時不會自動調用full_clean(),也不會因ModelForm驗證而調用該方法。然後,你可以到一個表單字典加上沒有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 )
你說得對,我將我的驗證進入形式,它更容易。我只是喜歡在模型中擁有一切的想法。 – Bastian 2012-01-08 07:02:40
@bastian,我也喜歡在模型中擁有一切。編寫新表單時很容易忘記業務規則,但如果業務規則在模型中則不會。出於這個原因,我已經將驗證從表單轉移到了模型中,正如我在我的文章中所解釋的。我很樂意瞭解新方法,如果它存在,可以用更優雅的方式來實現。無論如何我都避免在表單上寫驗證碼。 – danihp 2012-01-08 14:31:06
通過使用驗證器或者寫一個'clean()'方法來驗證你的模型是很好的。我只是說'save()'方法不是正確的地方。查看關於[驗證對象]的文檔(https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects)。 – Alasdair 2012-01-08 17:04:42