当前位置: 首页 > 面试题库 >

Django REST Framework中序列化程序验证的顺序

王扬
2023-03-14
问题内容

情况

在Django REST Framework的验证中工作时ModelSerializer,我注意到Meta.model字段总是被验证,即使这样做不一定有意义。以以下示例进行User模型的序列化:

  1. 我有一个创建用户的端点。因此,有一个password领域和一个confirm_password领域。如果两个字段不匹配,则无法创建用户。同样,如果所请求的username已经存在,则无法创建用户。
  2. 用户为上述每个字段发布了不正确的值
  3. validate已在序列化程序中实现的实现(请参见下文),以捕获不匹配passwordconfirm_password字段

实施validate

def validate(self, data):
    if data['password'] != data.pop('confirm_password'):
        raise serializers.ValidationError("Passwords do not match")
    return data

问题

即使ValidationError通过引发了validate,ModelSerializer仍然会查询数据库以查看username是否已在使用。从端点返回的错误列表中可以明显看出这一点。模型和非现场误差都存在。

因此,我想知道如何在非现场验证完成之前阻止模型验证,从而节省了对数据库的调用。

尝试解决

我一直试图通过DRF的源来找出发生这种情况的位置,但是我未能成功找到需要覆盖的内容才能使它起作用。


问题答案:

由于你的username字段很可能已unique=True设置,因此Django REST框架会自动添加一个验证器,该验证器将检查以确保新用户名是唯一的。实际上,你可以通过进行确认repr(serializer()),这将向你显示所有自动生成的字段,其中包括验证程序。

验证按特定的,未记录的顺序运行

  1. 字段反序列化称为(serializer.to_internal_valuefield.run_validators
  2. serializer.validate_[field] 被称为每个领域
  3. 称为序​​列化器级别的验证器(serializer.run_validation后跟serializer.run_validators
  4. serializer.validate
    因此,你看到的问题是在序列化程序级别的验证之前调用了字段级别的验证。虽然我不建议这样做,但是你可以通过extra_kwargs在serilalizer的meta中进行设置来删除字段级验证器。
class Meta:
    extra_kwargs = {
        "username": {
            "validators": [],
        },
    }

但是,你将需要unique在自己的验证中重新执行检查,以及已自动生成的任何其他验证器。



 类似资料:
  • 问题内容: 有没有一种方法可以验证在Mockito中是否曾经调用过a? 问题答案: 帮助您做到这一点。

  • 问题内容: Hibernate验证程序是否支持国际化。我看到了罐子,可以看到各种ValidationMessages.properties文件。 我们是否可以创建自己的将国际化的自定义错误消息?我不想使用Hibernate验证程序默认提供的错误消息。 我们需要使用我们自己的自定义消息,它们应该被国际化。 Hibernate验证程序支持哪些语言。在jar中,我看到了英语,法语,德语,土耳其语和蒙古语

  • 问题内容: 我想用Java验证HTML代码。 像这样: 有哪些Java库可以做到这一点? 问题答案: 您可以尝试JTidy。JTidy是HTML Tidy的Java端口,HTML Tidy是HTML语法检查器和漂亮的打印机。 http://jtidy.sourceforge.net/

  • 我们有一张350列的桌子。pojo类被生成,getter命令被打乱。试图使用jackson提供的csvmapper,但它会根据getter顺序生成csv@JsonPropertyOrder也不适合使用,因为有很多列。我们用xml维护列顺序,并且可以在运行时生成字段顺序数组。我们可以在运行时重写以提供属性排序的字段名数组吗?我们可以使用注释内省器进行自定义吗?

  • 我做了一个自定义验证规则,它迭代一个包含键

  • 环境 Glassfish 3.1.2内置Hibernate-Validator 4.2。