验证自定义Django字段

时间:2011-02-04 14:50:45

标签: django validation django-models django-admin

有一个Django字段类型用于存储MyType的值。

from django.core.exceptions import ValidationError
from django.db import models

class MyTypeField(models.Field):
    __metaclass__ = models.SubfieldBase

    def db_type(self, connection):
        return "text"

    def to_python(self, value):
        if isinstance(value, basestring):
            try:
                value = MyType.deserialize(value)
            except ParseError, e:
                raise ValidationError("Invalid format: "+str(e))
        assert isinstance(value, MyType)
        return value

    def get_prep_value(self, value):
        if not isinstance(value, MyType):
            raise ValidationError("Not MyType")
        return value.serialize()

我正在尝试在模型的管理页面上使用此类型的字段。如果用户在字段中输入有效值,则一切都很好。但是如果输入的值无效,则不会捕获ValidationError(如果启用了调试,则会收到错误500或堆栈跟踪)

相反,我希望在字段附近看到带有“无效格式”消息的表单(就像输入无效的日期或数字一样)。如何修改字段类以在正确的位置获取验证错误。

2 个答案:

答案 0 :(得分:4)

引自http://docs.djangoproject.com/en/1.2/howto/custom-model-fields/#modelforms-and-custom-fields

  

如果你使用SubfieldBase,to_python()   每次实例都会被调用   该字段的值被赋值。这个   意味着只要有价值   分配到该领域,你需要   确保它是正确的   数据类型,或您处理任何数据类型   异常。

因此,此时永远不会捕获ValidationError。从数据库填充模型的新实例时也会调用to_python,该数据库位于表单验证上下文之外。

  

因此,您必须确保   表单字段用于表示您的   自定义字段执行任何输入   验证和数据清理是   转换用户提供的必要   表格输入到   to_python() - 兼容的模型字段   值。这可能需要写一个   自定义表单字段和/或实现   你场上的formfield()方法   返回一个表单字段类   to_python()返回正确的   数据类型。

因此,您必须将验证移至表单域。

答案 1 :(得分:1)

您需要在字段类中创建clean(self, value, model_instance)方法并在那里进行验证/引发错误。