详解python中DRF框架的数据校验方式

 更新时间:2023年10月22日 08:12:37   作者:何如薄倖錦衣郎  
这篇文章主要为大家详细介绍了python中DRF框架的数据校验方式,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的小伙伴可以跟随小编一起了解一下

在使用DRF编写接口时,使用序列化器进行反序列化,校验数据大致分3步

  • 在获取反序列化的数据前,必须调用is_valid() 方法进行验证,验证成功返回True,否则返回False。
  • 验证失败,可以通过序列化器对象的errors属性获取错误信息,返回字典,包含了字段和字段的错误。如果是非字段错误,可以通过修改REST framework配置中的NON_FIELD_ERRORS_KEY来控制错误字典中的键名。
  • 验证成功,可以通过序列化器对象的validated_data属性获取数据。

一、继承Serializer

继承Serializer(序列化器基类,drf中所有的序列化器类都必须继承于 Serializer),直接写在参数里和写在函数

1.校验规则直接写在参数中

from rest_framework import serializers

class demoSerializer(serializers.Serializer):
    amount = serializers.IntegerField(max_value=100, min_value=0, error_messages={
        "min_value": "The Age Filed Must Be 0 <= amount",  # amount在反序列化必须是 0 <= amount <= 100
        "max_value": "The amount Filed Must Be amount <= 100",
    })

返回给前端:

class DemoAPIView(APIView):
     def post(self, request, *args):
       try:
          serializer = demoSerializer(data=request.data)
          serializer.is_valid(raise_exception=True)
          # 拿出已验证的数据中的data
          validated_data = ser.validated_data.get('amount')
          #  返回信息
          return Response({"msg": "ok", "data":validated_data}, status=status.HTTP_201_CREATED)
       except ValidationError as e:
           return Response({"msg": "error", "error_message": e.detail}, status=status.HTTP_401_UNAUTHORIZED)

在DRF的序列化器中,raise_exception是一个可选参数,用于控制是否在验证失败时引发ValidationError异常。它的默认值是False,即当验证失败时,不会引发异常,而是将错误消息存储在序列化器的errors属性中。 这里的e.detail指的就是demoSerializer中amount的error_message。

2、写在函数里

继承Serializer,写在定义的validate函数中,一种是外部函数,一种是内部,其中写在内部的又分为两种,一种是校验多个字段,一种是校验单个字段

a.外部函数

写一个校验函数,在demoSerializer以外,可以导入的形式

from rest_framework import serializers

def check_num(data):
        """外部验证函数"""
         if len(data) != 3:
         raise serializers.ValidationError(detail="num格式不正        确!必须是3个字符", code="check_num")
       # 验证完成以后,务必返回结果,否则最终的验证结果没有该数据
         return data
      
class demoSerializer(serializers.Serializer):
   num = serializers.CharField(validators=[check_classmate])
     

返回给前端方式和上面一样

b.写在内部函数里

内部又分为两个,写在demoSerializer里面,一种适合验证多个的validate函数,一种是验证单个的validate_name函数

验证多个字段

class demoSerializer(serializers.Serializer):
   name = serializers.CharField(required=True)   # required=True , 反序列化阶段必填
    sex = serializers.BooleanField(default=True)  # default=True,  反序列化阶段,客户端没有提交,则默认为True
   
   def validate(self, attrs):
        """
        验证来自客户端的所有数据
        类似会员注册的密码和确认密码,就只能在validate方法中校验
        validate是固定方法名,
        参数:attrs,是在序列化器实例化时的data选项数据
        """
        if attrs.get("name") == "xxx" and attrs.get("sex"):
            raise serializers.ValidationError(detail="错误信息xx", code="validate")

        return attrs

    def validate_name(self, data):
        """验证单个字段
        方法名的格式必须以 validate_<字段名> 为名称,否则序列化器不识别!
        validate开头的方法,会自动被is_valid调用的
        """
        if data in ["python", "django"]:
            # 在序列化器中,验证失败可以通过抛出异常的方式来告知 is_valid
            raise serializers.ValidationError(detail="错误信息", code="validate_name")
        # 验证成功以后,必须返回数据,否则最终的验证结果中,就不会出现这个数据了。
        return data  

返回前端方式如上

验证单个字段

class demoSerializer(serializers.Serializer):
  name = serializers.CharField(required=True,
validators=[validate_name])   # required=True , 反序列化阶段必填
   def validate_name(self, data):
       """验证单个字段
       方法名的格式必须以 validate_<字段名> 为名称,否则序列化器不识别!
       validate开头的方法,会自动被is_valid调用的
       """
       if data in ["python", "django"]:
           # 在序列化器中,验证失败可以通过抛出异常的方式来告知 is_valid
           raise serializers.ValidationError(detail="错误信息", code="validate_name")
       # 验证成功以后,必须返回数据,否则最终的验证结果中,就不会出现这个数据了。
       return data  

二、继承的是ModelSerializer

models.py:

from django.db import models
# Create your models here.
class DemoModel(models.Model):
    """信息"""
    price = models.IntegerField(verbose_name="价格")
    class Meta:
        db_table = "mysql_demo"
        verbose_name = "demotest"
        verbose_name_plural = verbose_name

此时serializers.py应该是:

from rest_framework import serializers
from .models import DemoModel  #一定要导入models,py里写的model

class DemoModelSerializer(serializers.ModelSerializer):
    #...... 其他代码
    class Meta:
        model = DemoModel
        fields = "__all__"
        extra_kwargs = {
            "age": {
                "max_value": 100,
                "error_messages": {
                    "max_value": "价格不能超过100!",
                }
            }
        }

fields = ["字段1","字段2",....] 我这里的all指的是所有的字段。 views.py返回给前端的代码和上面相同

到此这篇关于详解python中DRF框架的数据校验方式的文章就介绍到这了,更多相关python DRF数据校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python设计实现的计算器功能完整实例

    Python设计实现的计算器功能完整实例

    这篇文章主要介绍了Python设计实现的计算器功能,结合完整实例形式分析了Python3.5实现计算器功能的正则、字符串及数值运算等相关操作技巧,需要的朋友可以参考下
    2017-08-08
  • 解决.ui文件生成的.py文件运行不出现界面的方法

    解决.ui文件生成的.py文件运行不出现界面的方法

    今天小编就为大家分享一篇解决.ui文件生成的.py文件运行不出现界面的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06
  • flask框架url与重定向操作实例详解

    flask框架url与重定向操作实例详解

    这篇文章主要介绍了flask框架url与重定向操作,结合实例形式详细分析了flask框架URL映射、传参、重定向等相关概念、原理与操作注意事项,需要的朋友可以参考下
    2020-01-01
  • pip如何用pipdeptree查看包依赖

    pip如何用pipdeptree查看包依赖

    这篇文章主要介绍了pip如何用pipdeptree查看包依赖问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • 详解Python的Lambda函数与排序

    详解Python的Lambda函数与排序

    本篇文章主要是介绍了Python的Lambda函数与排序,简单的介绍了Lambda函数的用法和排序,有需要的朋友可以了解一下。
    2016-10-10
  • Python中read()、readline()和readlines()三者间的区别和用法

    Python中read()、readline()和readlines()三者间的区别和用法

    这篇文章主要给大家介绍了关于Python中读取文件的read()、readline()和readlines()方法三者间的区别和用法,需要的朋友可以参考下
    2017-07-07
  • Python利用filestools模块实现水印添加

    Python利用filestools模块实现水印添加

    最近发现的这款filestools非标准库其实真正实现添加水印的只要一个函数的调用,一行代码即可完成水印的添加,感兴趣的快跟随小编一起学起来吧
    2022-09-09
  • Python在CentOS系统中安装和配置的深度指南

    Python在CentOS系统中安装和配置的深度指南

    Python在CentOS系统上的安装和配置是许多开发者和系统管理员遇到的第一个挑战,本文将详细介绍一下CentOS安装配置Python的具体方法,希望对大家有所帮助
    2025-09-09
  • Python自然语言处理库之NLTK库初级教程

    Python自然语言处理库之NLTK库初级教程

    NLTK(Natural Language Toolkit)是一个Python库,用于实现自然语言处理(NLP)的许多任务,NLTK包括一些有用的工具和资源,如文本语料库、词性标注器、语法分析器等,在这篇初级教程中,我们将了解NLTK的基础功能,需要的朋友可以参考下
    2023-08-08
  • python制作websocket服务器实例分享

    python制作websocket服务器实例分享

    websocket是一个浏览器和服务器通信的新的协议,websocket则和一般的socket一样,使得浏览器和服务器建立了一个双工的通道。今天我们就来详细探讨下使用Python实现websocket服务器的具体方法
    2016-11-11

最新评论