我有一个名为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)
问题出在管理员表单中:当ValidationError
或clean()
方法中的某个字段引发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
会破坏管理表单。
答案 0 :(得分:4)
我已经找到了解决方案,感谢ojii指引我正确的方向。解释在docs关于SubfieldBase
。简而言之,因为我使用了__metaclass__ = models.SubfieldBase
,我需要继承forms.CharField
并从ValidationError
方法中提升to_python()
,然后在我的字段formfield()
中使用它方法而不是普通forms.CharField
。
答案 1 :(得分:0)
您不应在模型字段中提出forms.ValidationError
。而是在formfield
中返回的字段类中,实现接受validate
参数的value
方法。该方法可能会引发表单验证错误。