Django模型在后台的验证
这段内容提到了一些关于模型和字段验证的事情,类似于clean()方法在模型和字段验证中的应用,还有Django管理后台的验证错误(不过这个问题比较老,那个时候模型验证还不存在)。
我想用模型验证来让我的代码更简洁,但我遇到了一个奇怪的错误。我的模型是这样的:
from django.db import models
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
class Period(models.Model):
class Meta:
app_label = 'nps'
name = models.CharField(max_length=40)
start = models.DateField()
end = models.DateField()
def clean(self):
if self.start > self.end:
raise ValidationError(
_("Start date must be before end date"),
code='invalid',
)
super(Period, self).clean()
def validate_unique(self, exclude=None):
conflicts = Period.objects.filter(
start__lte=self.end,
end__gte=self.start,
)
if any(conflicts):
raise ValidationError(
_("Periods may not overlap."),
code='invalid',
)
super(Period, self).validate_unique(exclude)
def __unicode__(self):
return "%s (%s - %s)" % (self.name, self.start.strftime('%m/%d/%Y') or None, self.end.strftime('%m/%d/%Y') or None)
当我尝试保存一个无效的模型(比如开始日期在结束日期之后)时,我本以为会在管理页面看到一个验证错误,但实际上我得到了以下异常:
AttributeError at /admin/nps/period/add/
'ValidationError' object has no attribute 'error_dict'
Request Method: POST
Request URL: http://localhost:8000/admin/nps/period/add/
Django Version: 1.6.2
Exception Type: AttributeError
Exception Value:
'ValidationError' object has no attribute 'error_dict'
Exception Location: /opt/django_venv/local/lib/python2.7/site-packages/django/forms/models.py in _update_errors, line 327
Python Executable: /opt/django_venv/bin/python
Python Version: 2.7.3
Python Path:
['/opt/webapp',
'/home/vagrant/.pycharm_helpers/pydev',
'/opt/webapp',
'/vagrant',
'/opt/webapp/C',
'/Program Files (x86)/JetBrains/PyCharm 3.1.1/plugins/sass/lib/stubs/sass_functions.scss',
'/Python27',
'/opt/django_venv/lib/python2.7',
'/opt/django_venv/lib/python2.7/plat-linux2',
'/opt/django_venv/lib/python2.7/lib-tk',
'/opt/django_venv/lib/python2.7/lib-old',
'/opt/django_venv/lib/python2.7/lib-dynload',
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-linux2',
'/usr/lib/python2.7/lib-tk',
'/opt/django_venv/local/lib/python2.7/site-packages',
'/opt/webapp/webapp']
Server time: Tue, 8 Apr 2014 16:29:24 -0400
看起来管理模板期待的不是一个ValidationError
。我是不是做错了什么,还是说这是Django的一个bug?完整的错误信息可以在这里找到:https://gist.github.com/DBell-Feins/10170544
谢谢!
1 个回答
1
我之前也遇到过这个问题,经过一些尝试和错误后找到了解决办法。我在full_clean
这个方法里加了以下内容,不过在其他地方也应该能用。
from django.core.exceptions import ValidationError
from django.core.exceptions import NON_FIELD_ERRORS
class User(models.Model):
# ...
def full_clean(self, *args, **kwargs):
self.update_username_slug()
if User.objects.filter(username_slug=self.username_slug).exclude(id=self.id).exists():
raise ValidationError({
'username': [
ValidationError(
message='Username already exists',
code='unique',
params={},
)
]
})
super(User, self).full_clean(*args, **kwargs)
所以在你的情况下,你可能需要像这样做。
class Period(models.Model):
# ...
def clean(self):
if self.start > self.end:
raise ValidationError({
'start': [
ValidationError(
message=_("Start date must be before end date"),
code='invalid',
params={},
)
]
})
super(Period, self).clean()