繁体   English   中英

根据另一个字段的值验证 Django 模型字段?

[英]Validating a Django model field based on another field's value?

我有一个 Django 应用程序,其模型可通过 Django REST 框架和常规表单界面访问。 表单界面在保存对模型的更改之前有一些验证检查,但不使用任何特殊的 Django 框架,只是在视图中进行简单的本地更改。

我想对表单和 REST 调用应用相同的验证,所以我想将我的验证移到模型中。 我可以看到如何使用 Field 的验证器字段在简单情况下执行此操作,但在一种情况下,我有一个名称/类型/值模型,其中“值”的可接受值根据选择的类型而变化。 验证器不会收到有关该字段所在模型的任何信息,因此它无权访问其他字段。

如何在 DRF 的序列化程序和表单的 POST 视图中没有本质上相同的代码的情况下执行此验证?

我稍微挖掘了一下 drf 的代码库。 您可以使用以下方法获取所有字段的值,但文档中未提及。 这样做,您可以将序列化错误作为{'my_field':'error message}而不是{'non_field_error':'error message'}

def validate_myfield(self, value):
   data = self.get_initial() # data for all the fields
   #do your validation

但是,如果您希望为 ListSerializer 执行此操作,即对于serializer = serializer_class(many=True) ,这将不起作用。 您将获得空值列表。 在这种情况下,您可以在def validate函数中编写验证并避免序列化错误中的non_field_errors ,您可以使用错误消息作为字典而不是字符串来引发ValidationError

def validate(self, data):
    # do your validation
    raise serializers.ValidationError({"your_field": "error_message"})
 

当按如下方式定义时,每个字段的验证不会发送有关其他字段的任何信息:

def validate_myfield(self, value):
    ...

但是,如果您有这样定义的方法:

def validate(self, data):
    ...

然后你在一个字典中得到所有的数据,你就可以做跨领域的验证了。

您可以使用所需的包进行跨领域验证。 它允许您在 python 中声明性地表达您的验证规则。 使用 DRF 你会有这样的事情:

class MySerializer(serializers.Serializer):

    REQUIREMENTS = (
        Requires("end_date", "start_date") +
        Requires("end_date", R("end_date") > R("start_date")) + 
        Requires("end_date", R("end_date") < today.date() + one_year) + 
        Requires("start_date", R("start_date") < today.date() + one_year)
     )

    start_date = serializers.DateField(required=False, null=True, blank=True)
    end_date = serializers.DateField(required=False, null=True, blank=True)

    def validate(self, data):
        self.REQUIREMENTS.validate(data)  # handle validation error

您可以将REQUIREMENTS放在您的模型上,并让您的 DRF 和 Django 表单使用它来验证您的数据。

是一篇解释更多的博客文章

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM