在自定义字段中引发ValidationError to_python()方法会破坏管理表单

时间:2012-01-17 13:47:12

标签: django django-admin django-forms django-models

我有一个名为CustomField的自定义字段来包装一个名为Example的类,如下所示:

from django import forms
from django.db import models
from . import Example

class CustomField(models.CharField):
    __metaclass__ = models.SubfieldBase

    def to_python(self, value):
        try:
            return Example(value)
        except Example.InvalidValueException:
            raise forms.ValidationError('bad value!')

    def get_prep_value(self, value):
        return unicode(value)

    def formfield(self, **kwargs):
        defaults = {'form_class': forms.CharField}
        defaults.update(kwargs)
        return super(CustomField, self).formfield(**defaults)

问题出在管理员表单中:当ValidationErrorclean()方法中的某个字段引发validate()时,错误消息会整齐地显示在相应的输入字段旁边形成。但是,当它在我的自定义字段中的to_python()方法中引发时,无效值会非正常地破坏表单并显示一个错误页面,其中包含有关ValidationError的回溯。如何让我的字段与Django管理表单一起正常工作?

编辑:根据以下建议,我尝试了:

class CustomFieldForm(forms.CharField):
    def validate(self, value):
        raise forms.ValidationError('test')

并更改了formfield()方法以使用类:

    def formfield(self, **kwargs):
        defaults = {'form_class': CustomFieldForm}
        defaults.update(kwargs)
        return super(CustomField, self).formfield(**defaults)

然而,在to_python()方法之前仍然会调用CustomFieldForm.validate()方法,并且如果值无效,则前一方法中引发的Example.InvalidValueException会破坏管理表单。

2 个答案:

答案 0 :(得分:4)

我已经找到了解决方案,感谢ojii指引我正确的方向。解释在docs关于SubfieldBase。简而言之,因为我使用了__metaclass__ = models.SubfieldBase,我需要继承forms.CharField并从ValidationError方法中提升to_python(),然后在我的字段formfield()中使用它方法而不是普通forms.CharField

答案 1 :(得分:0)

您不应在模型字段中提出forms.ValidationError。而是在formfield中返回的字段类中,实现接受validate参数的value方法。该方法可能会引发表单验证错误。