Python 管理中的Django模型验证

Python 管理中的Django模型验证,python,django,validation,django-models,django-admin,Python,Django,Validation,Django Models,Django Admin,类似于和(尽管这一个已经足够老了,在模型验证存在之前就得到了回答) 我试图使用模型验证来保持代码的干燥,但我一直遇到一个奇怪的错误。我的模型看起来是这样的: from django.db import models from django.core.exceptions import ValidationError from django.utils.translation import ugettext as _ class Period(models.Model): class M

类似于和(尽管这一个已经足够老了,在模型验证存在之前就得到了回答)

我试图使用模型验证来保持代码的干燥,但我一直遇到一个奇怪的错误。我的模型看起来是这样的:

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?可在此处找到完整的stacktrace:


谢谢

我也遇到了同样的问题,经过反复试验后找到了解决方案。我在
full\u 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()