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

情况

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

  • 我有一个创建用户的端点。因此,存在一个password字段和一个confirm_password字段。如果两个字段不匹配,则无法创建用户。同样,如果请求的username已经存在,则无法创建用户。
  • 用户为上面提到的每个字段POST输入了不正确的值
  • 在序列化程序中(参见下文)实现了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 Framework自动添加一个验证程序,以检查新用户名是否唯一。您实际上可以通过执行repr(serializer())来确认这一点,该操作将向您显示所有自动生成的字段,其中包括验证程序。

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

  • 称为( serializer.to_internal_valuefield.run_validators )的字段反序列化
  • 每个字段都会调用 serializer.validate_[field]
  • 称为序列化程序级别的验证器( serializer.run_validation 后跟 serializer.run_validators )
  • serializer.validate 称为
  • 因此,您看到的问题是在序列化程序级别的验证之前调用了字段级别的验证。尽管我不建议这样做,但您可以通过在Serilalizer的meta元素中设置extra_kwargs来删除字段级验证器。

    class Meta:
        extra_kwargs = {
            "username": {
                "validators": [],
            },
        }
    

    不过,您将需要在自己的验证中重新实现unique检查,以及自动生成的任何其他验证器。

    Django BigInteger自动递增字段作为主键? - python

    我目前正在建立一个涉及大量集体智慧的项目。每个访问该网站的用户都将创建一个唯一的配置文件,然后将他们的数据用于为自己和其他用户计算最佳匹配。默认情况下,Django创建一个INT(11)id字段来处理模型的主键。我担心这会很快溢出(即,大约2.4b个设备在未事先设置Cookie的情况下访问了该页面)。如何在MySQL中将其更改为BIGINT并在Django自…

    Django Python日期时间设置为午夜 - python

    我有django对象的日期时间,但可以是一天中的任何时间。它可以是一天中的任何时间,但我需要将时间设置为00:00:00(另一个日期设置为23:59:59,但原理是相同的)end_date = lastItem.pub_date 当前的结束日期是2002-01-11 12:34:56我需要怎么做才能将其更改为00:00:00?我试过了:end_date.ho…

    Django:使用contenttypes框架的一般关系示例? - python

    我已经多次浏览了有关contenttypes框架的Django文档,但我对它的理解不足以在项目中实现泛型关系。我一直在寻找有关此事的在线示例或教程,但找不到一个。称我为哑巴,但在这方面我需要一些帮助(请不要仅通过链接到文档来回答问题)。基于在线资源的缺乏,我相信如果您用一个完整的例子来回答这个问题,您的答案可能是迄今为止有关django通用关系(奖金!)的最…

    Django:错误:您无权访问该端口 - python

    我是整个安装的新手,请保持友善。在dev上,该命令通常可以正常工作,但是自从我尝试使用Django的不同命令以来,某些东西就出错了。python manage.py runserver 0.0.0.0:80 我没有使用此端口的权限了。我可以使用端口8080,但将端口添加到url中通常的主机名末尾时,网站无法正常工作。当我使用端口80时,无论如何我都无需在UR…

    django-getlist() - python

    我刚刚发布了这个问题jQuery - passing arrays in post request,在发布请求中我不发送数组,但是jQuery代码没有问题。问题在于在django中接收到POST请求。我确实喜欢这个def portfolio_add(request): ukeys = request.POST.getlist('ukeys'…