バスティアンは、私は私のコードのテンプレートあなたに説明し、私はあなたに役立ちます願っています。 modelformsを使用する場合、フォーム検証時にinstance.full_clean()が呼び出されます。各モデルで
私は(のModelFormの検証に、このメソッドが自動的に(full_cleanから呼び出される))カスタム関数でclean()
メソッドを上書き:
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
ファイルに私は商務ルールを記述します。また、私は間違った状態でモデルを救う防ぐために、私のカスタム関数に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 %}
理由は、モデル検証errosのアラがnon_field_errorsエラー辞書のエントリにバインドさという点です。
あなたはエラーが発生することができることを覚えておいてくださいフォームのうち、モデルを保存または削除:
try:
issue.delete()
except ValidationError, e:
import itertools
errors = list(itertools.chain(*e.message_dict.values()))
また、あなたがいない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 )
このコードはsave()メソッドでは実行されないことに注意してください。モデルのsave()メソッドを呼び出すとき、またはModelForm検証の結果としてfull_clean()が自動的に呼び出されることはありません。その後、あなたはなしmodelforms上のフォーム辞書にエラーを追加することができますだけでなくValidationErrorををインポートするようにしてください
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
@bastian、私はモデルのすべてを持っていることも好きだった。新しいフォームを書くときビジネスルールを忘れるのは簡単ですが、ビジネスルールがモデルにある場合はそうではありません。この理由から私は自分の投稿で説明するように、フォームからモデルに検証を移しました。私はそれが存在する場合、よりエレガントな方法でこれを行う新しい方法について学ぶために開いています。いずれにしても、フォームに検証コードを書くことは避けてください。 – danihp
バリデータを使用するか、 'clean()'メソッドを書くことでモデルにバリデーションを入れることは良いことです。私が言っていたのは、 'save()'メソッドは正しい場所ではないということです。 [validating objects](https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects)のドキュメントをご覧ください。 – Alasdair