モデルのsaveメソッドで検証エラーを適切に発生させ、ユーザーに明確なメッセージを送り返す方法がわかりません。
基本的に、「if」の各部分、エラーを発生させたい部分と実際に保存する部分を終了する方法を知りたいです。
def save(self, *args, **kwargs):
if not good_enough_to_be_saved:
raise ValidationError
else:
super(Model, self).save(*args, **kwargs)
次に、たとえば値が一意でない場合にDjangoが自動的に返すように。 (ModelForm)およびモデルのすべてを調整します。
ほとんどのDjangoビューたとえばDjango adminはsaveメソッドで検証エラーを処理できないため、ユーザーは500エラーを受け取ります。
モデルフォームまたはモデルで検証を行い、そこでValidationError
を上げる必要があります。次に、モデルフォームデータが「保存するのに十分な」場合にのみ、save()
を呼び出します。
バスティアン、私はあなたに私のコードテンプレートを説明します、それがあなたに役立つことを願っています:
Django 1.2では、モデルに検証コードを記述できます 。モデルフォームを操作する場合、フォームの検証時にinstance.full_clean()が呼び出されます。
各モデルでclean()
メソッドをカスタム関数で上書きします(このメソッドは、モデルフォームの検証時にfull_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はモデルのcleanメソッドを呼び出し、custon関数が正しい状態をチェックするか、モデルフォームによって処理されるエラーを発生させます。
フォームにエラーを表示するには、フォームテンプレートにこれを含める必要があります。
_{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
{{error}}
{% endfor %}
{% endif %}
_
その理由は、モデル検証エラーがnon_field_errorsエラーディクショナリエントリにバインドされているためです。
フォームからモデルを保存または削除するとき、エラーが発生する可能性があることを覚えておく必要があります。
_try:
issue.delete()
except ValidationError, e:
import itertools
errors = list( itertools.chain( *e.message_dict.values() ) )
_
また、モデルフォームなしでフォーム辞書にエラーを追加できます。
_ 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()は自動的に呼び出されないことに注意してください。次に、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 )
_
validationErrorも必ずインポートしてください
from Django.core.exceptions import ValidationError
def clean(self):
raise ValidationError("Validation Error")
def save(self, *args, **kwargs):
if some condition:
#do something here
else:
self.full_clean()
super(ClassName, self).save(*args, **kwargs)
これは、Django 1.2+
フォームでは、non_field_errorとして発生します。他のケースでは、DRFのように、500エラーになるため、このケースのマニュアルを確認する必要があります。
class BaseModelExt(models.Model):
is_cleaned = False
def clean(self):
# check validation rules here
self.is_cleaned = True
def save(self, *args, **kwargs):
if not self.is_cleaned:
self.clean()
super().save(*args, **kwargs)