python - 我应该在哪里对对象和字段进行 Django 验证?

标签 python django validation django-rest-framework

我正在创建一个 Django 应用程序,它同时使用 Django Rest Framework 和普通的 django-views 作为用户的入口点。

我想对模型的独立字段以及整个对象进行验证。例如:

  • 字段:根据正则表达式函数输入的车牌是否正确。与其他领域无关。

  • 对象:输入的邮政编码对给定国家是否有效。与模型中的邮政编码和国家/地区相关。

对于 DRF-API,我使用 ModelSerializers,它会自动调用我在模型中放置的所有验证器,例如:

class MyModel(models.Model):
    licence_plate = CharField(max_length=20, validators=[LicencePlateValidator])

由于模型中给出了验证器,API POSTS(因为我使用了 ModelSerializer)以及在 django 管理后端中创建的对象都被验证了。

但是当我想引入对象级验证时,我需要在序列化程序的 validate() 方法中执行此操作,这意味着对象仅在 API 中进行验证。

我还必须覆盖模型的保存方法,以验证在 Django 管理页面中创建的对象。

问题:这对我来说似乎有点困惑,是否有一个点可以放置对象级验证器,以便它们在 API 和管理页面中运行,比如我做了字段级验证(我只需要将它们放在我的模型声明中,一切都已处理)

最佳答案

对于模型级验证,有 Model.clean 方法。

如果您使用 ModelForm(在 admin 中默认使用),它会被调用,因此这解决了 django View 和管理部分。

另一方面,DRF 不会自动调用模型的 clean,因此您必须在 Serializer.validate 中自己执行此操作(如 doc 所建议的那样).您可以通过序列化器混合来完成:

class ValidateModelMixin(object)
    def validate(self, attrs):
        attrs = super().validate(attrs)
        obj = self.Meta.model(**attrs)
        obj.clean()
        return attrs

class SomeModelSerializer(ValidateModelMixin, serializers.ModelSerializer):
    #...
    class Meta:
        model = SomeModel

或者写一个验证器:

class DelegateToModelValidator(object):

    def set_context(self, serializer):
        self.model = serializer.Meta.model

    def __call__(self, attrs):
        obj = self.model(**attrs)
        obj.clean()

class SomeModelSerializer(serializers.ModelSerializer):
    #...
    class Meta:
        model = SomeModel
        validators = (
            DelegateToModelValidator(),
        )

注意事项:

  • 模型的额外实例化只是为了调用 clean
  • 你仍然需要将 mixin/validator 添加到你的序列化器中

关于python - 我应该在哪里对对象和字段进行 Django 验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32921956/

相关文章:

python - 将宽字符转换为 python 字符串时可能发生内存泄漏

python - 使用标准 django.contrib.auth.models.User 模型在 Sqlite 数据库中查询用户名 "x"的用户

android - 验证硬编码密码

python - 如何使用 Mysql Python 连接器检索二进制数据?

python - 代理功能适用于请求,但不适用于 chrome 浏览器?

python - Django 装饰器@transaction.non_atomic_requests 在 ViewSet 方法中不起作用

python - 为什么我的 Django 应用程序模型的字段值没有改变?

python - 属性错误 : VerifiedHTTPSConnection instance has no attribute '_tunnel_host'

c# - 使用自定义 ValidationResult 处理数据注释验证

javascript - 使用 AJV 解析无效对象的自定义架构