在使用DRF进行反序列过程中,总是需要校验字段,然后返回错误结果。可以使用默认的自定义校验项,也可以自定义校验项。而默认的自定义校验项总是差强人意。

版本

  1. Django 2.2.3
  2. Python 3.8.8
  3. djangorestframework 3.13.1

目标效果

默认错误返回效果 —— 默认校验函数

默认错误返回 —— 默认校验函数


  1. def validate(self, attrs):
  2. """
  3. 验证字段
  4. """
  5. # 确认手机号是否唯一
  6. user = User.objects.get(mobile=attrs.get('mobile'))
  7. print(user)
  8. if user:
  9. raise serializers.ValidationError(detail={'status': 1, 'message': '当前手机号码已经被注册!', 'data': None})

默认错误返回效果 —— 自定义校验函数

采用自定义校验函数之后,返回格式有所改善,但是此种返回都是以字段名为key,自定义的内容格式成为了这个key的value。

默认错误返回 —— 自定义校验函数

  1. def validate_mobile(self, mobile):
  2. """
  3. 验证手机号
  4. """
  5. try:
  6. # 确认手机号是否唯一
  7. user = User.objects.get(mobile=mobile)
  8. print(user)
  9. if user:
  10. raise serializers.ValidationError(detail={'status': 1, 'message': '当前手机号码已经被注册!', 'data': None})
  11. except User.DoesNotExist:
  12. pass
  13. return mobile

自定义校验函数说明

  • 方法名必须以validate_作为前缀,后缀为对应的字段名:如validate_mobile中的mobile即为模型的一个字段
  • 一定要返回校验之后的值:return mobile
  • 不需要放在validators的列表中就可以生效(暂未理解为何意)

避坑: 方法名前缀是validate_为前缀,而不是validated_为前缀。Pycharm提示时会出现 validated_xxx ,此时多了一个d

自定义ValidationError返回

  1. # -*- coding:utf-8 -*-
  2. # author: F0080
  3. # Python 3.8.8
  4. # FilePath: 项目/utils/validation_error.py,如demo/utils/validation_error.py
  5. # FilePath可随意定义,但注意后面引入路径
  6. from django.utils.translation import ugettext_lazy as u_
  7. from rest_framework import status
  8. from rest_framework.exceptions import APIException, ErrorDetail
  9. from rest_framework.utils.serializer_helpers import ReturnList, ReturnDict
  10. def get_error_details(data, default_code=None):
  11. if isinstance(data, list):
  12. ret = [
  13. get_error_details(item, default_code) for item in data
  14. ]
  15. if isinstance(data, ReturnList):
  16. return ReturnList(ret, serializer=data.serializer)
  17. return ret
  18. elif isinstance(data, dict):
  19. ret = {
  20. key: get_error_details(value, default_code) for key, value in data.items()
  21. }
  22. print(ret)
  23. if isinstance(data, ReturnDict):
  24. return ReturnDict(ret, serializer=data.serializer)
  25. return ret
  26. code = getattr(data, 'code', default_code)
  27. # 返回一个对象属性值
  28. return ErrorDetail(data, code)
  29. class ValidationError400(APIException):
  30. status_code = status.HTTP_400_BAD_REQUEST
  31. default_detail = u_('Invalid input.')
  32. default_code = 'invalid'
  33. def __init__(self, detail=None, code=None):
  34. if detail is None:
  35. detail = self.default_detail
  36. if code is None:
  37. code = self.default_code
  38. if not isinstance(detail, dict) and not isinstance(detail, list):
  39. detail = [detail]
  40. self.detail = get_error_details(detail, code)

在serializers.py中使用自定义ValidationError

  1. from demo.utils.validation_error.py import ValidationError400
  2. ...
  3. def validate_mobile(self, mobile):
  4. """
  5. 自定义校验函数——验证手机号
  6. """
  7. try:
  8. # 确认手机号是否唯一
  9. user = User.objects.get(mobile=mobile)
  10. print(user)
  11. if user:
  12. raise ValidationError400(detail={'status': 1, 'message': '当前手机号码已经被注册!', 'data': None})
  13. except User.DoesNotExist:
  14. pass
  15. return mobile
  16. def validate(self, attrs):
  17. """
  18. 默认校验函数——验证密码
  19. """
  20. password = attrs.get('password')
  21. # 验证密码长度6-16位
  22. if not re.match('^.{6,16}$', password):
  23. raise ValidationError400(detail={'status': 1, 'message': '密码长度必须在6-16位之间!', 'data': None})
  24. ...

致谢大佬

rest_framework serializers ValidationError 错误信息自定义 key 值

DjangoRestFramework ModelSerializer:字段级验证不起作用

自定义 serializers.ValidationError 的错误返回的更多相关文章

  1. TCP connect的错误返回值

    如果是TCP套接字,调用connect函数将激发TCP三次握手过程,而且仅在连接建立成功或出错时返回,其中错误返回可能有下面几种情况: (1)若TCP客户没有收到SYN分节的响应,则返回ETIMEDO ...

  2. Spring验证的错误返回------BindingResult

    Spring验证的错误返回------BindingResult 参考资料:http://www.mkyong.com/spring-mvc/spring-mvc-form-errors-tag-ex ...

  3. phpcms v9自定义表单提交后返回上一页实现方法

    PHPcms v9中提交自定义表单后默认都是回到首页的,是不是感觉很不爽! 接下来,就说下phpcms v9自定义表单提交后返回上一页实现方法. 1.找到这个文件 phpcms\modules\for ...

  4. Struts2自定义Field级别的错误提示信息

    自定义Field级别的错误提示信息步骤: 在action包中新建一个以Action命名的properties文件,如:RegisterAction.properties 2. 然后在该属性文件中指定每 ...

  5. jQuery ajax请求错误返回status 0和错误error的问题

    上周发现一个jQuery ajax请求错误返回status 0和错误error的问题,responseText是"error",状态码是0而不是200: $.ajax({ type ...

  6. 14、SpringBoot------定制错误返回内容json格式

    开发工具:STS 前言: 在前后端分离的项目中,当前端向后端请求资源失败时,想知道具体的错误原因,给用户予以提示. 但是,在springboot中返回内容是固定的.并不适合我们前端进行分析. 所以,就 ...

  7. Laravel自定义错误提示,自定义异常类提示,自定义错误返回信息,自定义错误页面

    方法一 新增CustomException.php文件 App\Exceptions\CustomException.php <?php namespace App\Exceptions; us ...

  8. 自定义 404 与 500 错误页面,URL 地址不会重定向(一)

    对于 404 与 500 错误发生时,我们希望自己定义一个更加人性化的页面. 例子 当访问下面这个地址时: http://localhost/aaaa/bbb/ccc/ddd/eee/fff/ggg ...

  9. 解决spring boot中rest接口404,500等错误返回统一的json格式

    在开发rest接口时,我们往往会定义统一的返回格式,列如: { "status": true, "code": 200, "message" ...

随机推荐

  1. django之定义统一返回数据格式与GET/POST装饰器

    1. 为了返回给网页前端的格式统一,定义一个通用的插件类,返回统一格式数据 # enconding:utf-8 """ 定义一个插件类, ""&quo ...

  2. AT2163 [AGC006B] Median Pyramid Easy

    需要一点灵感的题目. 可以发现这样一个事情,当三个数中有两个数相同时,中为数一定是这两个相同的数. 基于这个观察,我们想让每一行都存在这样两个相同的两个数,就一定能保证第一层的值为 \(x\) 了. ...

  3. synchronized、ReentrantLock、volatile

    名词解释 synchronized 是Java中的关键字,是一种同步锁,可以修饰代码块,方法,静态的方法,类.synchronized(Object) 不能用String常量.Integer. Lon ...

  4. ExcelPackage 使用說明

    1.使用方法 public IActionResult Excel() { string sWebRootFolder = _hostingEnvironment.WebRootPath; strin ...

  5. 【转】zabbix监控mysql

    纯属搬家收藏,原文链接 https://www.cnblogs.com/shenjianyu/p/6627843.html 注意: 1.关注的重点在agent端部分 2.zabbix_get命令没有, ...

  6. new方法实现原理

    new方法实现原理 完整的创建一个可用的对象:Person *p=[Person new]; new方法的内部会分别调用两个方法来完成3件事情: (1)使用alloc方法来分配存储空间(返回分配的对象 ...

  7. docker基础——1.原理解读

    1. 相关内核知识 docker本质上是宿主机上的进程. 通过namespace实现资源隔离,通过cgroups实现资源限制,通过写时复制机制copy-on-write实现高效文件操作. 依赖kern ...

  8. P2678 [NOIP2015 提高组] 跳石头

    #include<bits/stdc++.h> using namespace std; int l,n,m,a[100010];//与起点的距离 bool check(int d) { ...

  9. Ubuntu20.04 PostgreSQL 14 安装配置记录

    PostgreSQL 名称来源 It was originally named POSTGRES, referring to its origins as a successor to the Ing ...

  10. 3、Linux基础--cp、mv、rm、alias、vi/vim命令

    笔记 1.考试 1.判断网络是否通畅的命令 ping 2.定义系统提示组成的变量 PS1 3.Linux中目录从什么开始 根(/) 4.系统中目录路径类型有哪些,解释一下 绝对路径:以根目录作为参照物 ...