自定义 Django 字段的验证

发布于 2024-10-16 01:33:46 字数 958 浏览 1 评论 0原文

有一个 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,或者如果启用了调试,则会出现堆栈跟踪)

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

There is a Django field type for storing values of 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()

I am trying to use fields of this type on an admin page of a model. Everything works nice if a user enters a valid value in the field. But if the entered value is invalid, the ValidationError is not caught (you get error 500, or a stack trace if debug is enabled)

Instead I want to see the form with a message "Invalid format" near the field (just like if you enter an invalid date or number). How to modify the field class to get validation errors in a correct place.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

童话里做英雄 2024-10-23 01:33:46

引用自 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() 返回正确的
数据类型。

因此,您必须将验证移至表单字段中。

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

If you use SubfieldBase, to_python()
will be called every time an instance
of the field is assigned a value. This
means that whenever a value may be
assigned to the field, you need to
ensure that it will be of the correct
datatype, or that you handle any
exceptions.

So a ValidationError will never be caught at this point. to_python is also called when populating a new instance of your model from the database, which is outside the form validation context.

Therefore, you must ensure that the
form field used to represent your
custom field performs whatever input
validation and data cleaning is
necessary to convert user-provided
form input into a
to_python()-compatible model field
value.
This may require writing a
custom form field, and/or implementing
the formfield() method on your field
to return a form field class whose
to_python() returns the correct
datatype.

So you have to move your validation into a formfield.

女皇必胜 2024-10-23 01:33:46

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

You need to create a clean(self, value, model_instance) method in your field class and do the validation/raise the error there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文