Bas*_*ian 56 django validation model validationerror
我不确定如何在模型的保存方法中正确引发验证错误,并向用户发回明确的消息.
基本上我想知道"if"的每个部分应该如何结束,我想要引发错误的部分和它实际保存的部分:
def save(self, *args, **kwargs):
if not good_enough_to_be_saved:
raise ValidationError
else:
super(Model, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
然后我想知道该怎么做才能发送一个验证错误,该错误确切地告诉用户错误就像Django自动返回的那样,例如,如果某个值不唯一.我正在使用(ModelForm)并从模型中调整所有内容.
Ala*_*air 52
大多数Django视图,例如Django管理员将无法处理save方法中的验证错误,因此您的用户将获得500个错误.
您应该在模型表单或模型上进行验证,并ValidationError
在那里进行验证.然后save()
仅在模型表单数据"足够好以保存"时调用.
dan*_*era 25
巴斯蒂安,我向你解释我的代码模板,我希望对你有所帮助:
从django 1.2开始,它能够在模型上编写验证代码.当我们使用modelforms时,在表单验证时调用instance.full_clean().
在每个模型中,我clean()
使用自定义函数覆盖方法(此方法在modelform验证时自动从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()
Run Code Online (Sandbox Code Playgroud)
然后在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
Run Code Online (Sandbox Code Playgroud)
然后,modelform调用模型的clean方法和我的custon函数检查正确的状态或引发由模型表单处理的错误.
为了在表单上显示错误,您应该将其包含在表单模板中:
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
{{error}}
{% endfor %}
{% endif %}
Run Code Online (Sandbox Code Playgroud)
原因是模型验证错误ara绑定到non_field_errors错误字典条目.
当您从表单中保存或删除模型时,您应该记住可能会引发错误:
try:
issue.delete()
except ValidationError, e:
import itertools
errors = list( itertools.chain( *e.message_dict.values() ) )
Run Code Online (Sandbox Code Playgroud)
此外,您可以在没有模型的情况下向表单字典添加错误:
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 )
Run Code Online (Sandbox Code Playgroud)
请记住,此代码不是在save()方法上执行的:请注意,调用模型的save()方法时,不会自动调用full_clean(),也不会因模型化验证而自动调用.然后,您可以在没有模型的情况下向表单字典添加错误:
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 )
Run Code Online (Sandbox Code Playgroud)
我认为这是 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)
Run Code Online (Sandbox Code Playgroud)