DRF的认证、权限、限流、序列化、反序列化

news2024/11/28 18:43:44

DRF的认证、权限、限流、序列化、反序列化

  • 一、认证
    • 1、直接用,用户授权
    • 2、认证组件源码
  • 二、权限
    • 1. 直接使用,用户权限
    • 2.权限组件源码
  • 三、序列化
    • 1. 序列化
      • 1.1 自定义Serailizer类序列化
      • 1.2 在视图APIView中使用
      • 1.3 自定义ModelSerializer类序列化
      • 1.4 不同格式的字段序列化
          • 1.4.1 自定义字段
          • 1.4.2 日期自定义格式
          • 1.4.3 自定义方法字段
          • 1.4.4 嵌套,针对:一对多,多对多的情况
          • 1.4.5 继承
    • 2. 序列化-源码流程
  • 四、反序列化
    • 1. 反序列化流程
    • 2. 数据校验
      • 2.1数据校验是要在视图中校验的。但要在序列化类中写好校验规则。
      • 2.2序列化类校验规则
        • 2.2.1内置校验规则
        • 2.2.2 正则校验规则
        • 2.2.3 钩子函数
        • 2.24 ModelSerializer校验规则
        • 2.2.5 字段属性(read_only,write_only)
        • 2.2.6对校验的总结
    • 3.序列化字段与模型字段的总结
      • 3.1 对于chioces与序列化、反序列化、模型字段名一致
    • 4. 数据校验-源码流程
  • 五、模型查询的常规操作

一、认证

1、直接用,用户授权

  • 实现方法

    • 编写 ->认证组件

    • 应用组件

  • 编写 ->认证组件

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
class 认证类(BaseAuthentication):
    def authenticate(self,request):
        1、 获取用户信息
        	1.1 可以从URL中获取,xx/xx/xx/?token=....
            	request.query_params(token) 来获取token值
            1.2 可以从请求头中获取
            	request.META.get("HTTP_AUTHORIZATION")
                # AUTHORIZATION传递过来的key
            1.3 可以从请求体中获取
            	request.data.get(token)
        2、校验用户信息的合法性
        3、返回结果
           - 3.1 正确,返回元组(用户信息,认证信息如token)
           - 3.2 错误,raise抛出错误信息
        		raise AuthenticationFailed({key:vaule})
            	#注:可以用字典提示错误
           - 3.3 错误返回None->多个认证类 [1,类2....]
        return user,auth
    def authenticate_header(self,request):
        return "token"
    #认证失败状态应该是401,如果authenticate_header不返回值,就是403

​ BaseAuthentication源码是:

class BaseAuthentication:
    #注:只要在django中出现raise NotImplementedError(),就必须使用该方法,不然会出错!(重定义方法)。子类约束。
    def authenticate(self,request):
        raise NotImplementedError("必顺要写的函数。")
    def authenticate_header(self,request):
        pass
  • 应用组件
    • 局部
from rest_framework.views import APIView
from rest_framework.response import Response
#在视图类中添加
class 视图类名(APIView):
    authentication_classes = [认证类1,认证类2,认证类3.....]
  • 全局(在setting中设置)

    REST_FRAMEWORK = {
        "UNAUTHENTICATED_USER":None,#是让没有用户时为None,默认是AnyOne,
        "DEFAULT_AUTHENTICATION_CLASSES":["自定义认证类的位置"]
    }
    # 注:在配置全局时,不能写在视图类中。视图类还没有加载完。
    

    在全局配置时,如果要让某个视图不进行认证,就在视图类中把authentication_classes=[]

  • 注:

    • 多个认证类
      多个认证类是或的关系,但返回的值是None,前面的认证成功,后面的就不认证了。如果都不认证成功,一般最后一个为抛出异常类。
      抛出异常类

      class NoAuthentictions(BaseAuthentication):
          def authenticate(self,request):
              raise AuthenticationFailed({key:vaule})
           def authenticate_header(self,request):
              return 'Token'
      

回顾
请添加图片描述

2、认证组件源码

二、权限

1. 直接使用,用户权限

  • 权限组件说明
    在这里插入图片描述

  • 权限组件编写

from rest_framework.permissions import BasePermission

class 权限类名(BasePermission):
    messge={.....}#权限失败是返回的错误信息
    def has_permission(self,request,view):
        1. 获取请求中的数据
        2. 校验
        3. 返回值
            3.1 返回True 表示校验通过
            3.2 返回False 表示校验没通过
     	return True | False
  • 权限组件的使用

    • 局部使用(在视图中添加)
    from rest_framework.views import APIView
    
    class 视图类名(APIView):
        permission_classes = [权限类名1,权限类名2,权限类名3....]
        #权限类名是一个且的关系,前面的是False后面的就不再执行了。
    
    • 全局(setting.py)中

    • REST_FRAMEWORK = {
          "UNAUTHENTICATED_USER":None,#是让没有用户时为None,默认是AnyOne,
          "DEFAULT_AUTHENTICATION_CLASSES":["自定义认证类的位置"],
          "DEFAULT_PERMISSION_CLASSES":["自己定义的权限类位置"]#可以是一个列表
      }
      # 注:在配置全局时,不能写在视图类中。视图类还没有加载完。
      
  • 权限或组件的编写

    系统默认的是且关系,而不是或的关系,以下是或的关第编写

#要在APIView中编写代码
from rest_framework.views import APIView

class 自定义或权限关系类名(APIView):
    def check_permission(self,request):
        permission_objects = self.get_permissions()
        for permission in permission_objects:
            if permission.has_permission(request,self):
                return
        else:
            self.permission_denied(
            	request,
                message=getattr(permission_objects[0],'message',None),
                code=getattr(permission_objects[0],'code',None)
            )
for...in...:
    ....
else:
    ....
#当循环完后,有返回False时,才执行else

在视图类中,继承自定义或权限关系类名

2.权限组件源码

三、序列化

1. 序列化

序列化,从数据库获取Query_Set或数据对像 ->JSON

序列化的流程

路由->视图->去数据库获取对象或QuerySet -> 序列化器的类转换成列表、字典、有序字典 -> JSON处理

1.1 自定义Serailizer类序列化

from rest_framework import serializers
class 序列化类名(serializers.Serializer):
    字段 = serializers.类型()
    ...
    
 #字段要与数据库中的一致

1.2 在视图APIView中使用

from rest_framework.views import APIView
frrom rest_framework.response import Response
class 视图类名(APIView):
    1. 获取数据库的数据instance
    2. 序列化数据
    ser = 序列化类名(instance = instance,many=True | False)#True是Query_Set,False是数据对像
    #ser.data才是真正的将数据对象或Query_set转化为JSON格式
    3.返回JSON数据
    return Response(ser.data)

关于序列化类many的说明

  • many=False是单个对象的序列化
  • many=True时是Query_set的序列化,它是加了下个for循环,再调用单个对象序列化

1.3 自定义ModelSerializer类序列化

由于序列化时,字段与模型中的字段是一样的,所以将其集中

from from rest_framework.serializers import ModelSerializer
class 自定义ModelSerializer类名(ModelSerializer):
    class Meta:
        model = 模型类名
        fields = [字段类名列表] | "__all__"#所有字段都返回

1.4 不同格式的字段序列化

1.4.1 自定义字段

在modelserializer的字段自定制

from from rest_framework.serializers import ModelSerialize
from from rest_framework.serializers
class 自定义ModelSerializer类名(ModelSerializer):
    字段 = serailizes.类型(source="数据库的字段")#自定义字段,要在field中添加自定义字段名
    class Meta:
        model = 模型类名
        fields = [字段类名列表] | "__all__"#所有字段都返回

注:

  • source是数据库的字段
  • source支持对象的访问,如obj.字段.外键字段名 | obj.get_字段_display#get_字段_display运行时会自动加上括号
  • 在fields中要添加自定义字段名,可以不与数据名一致

1.source对接的是数据库。2.支持orm对数据库的操作。3.带有函数的不用加括号。

1.4.2 日期自定义格式
from from rest_framework.serializers import ModelSerialize
from from rest_framework.serializers 
class 自定义ModelSerializer类名(ModelSerializer):
    日期字段 = serailizes.DateTimeField(format="%y-%m-%d") #日期格式显式
    class Meta:
        model = 模型类名
        fields = [字段类名列表] | "__all__"#所有字段都返回
1.4.3 自定义方法字段
from from rest_framework.serializers import ModelSerialize
from from rest_framework.serializers 
class 自定义ModelSerializer类名(ModelSerializer):
    自定义方法字段 = serailizes.SerializerMethodField()
    class Meta:
        model = 模型类名
        fields = [字段类名列表] | "__all__"#所有字段都返回
        
    def get_自定义方法字段(self,obj):
        obj是对象值
        retrun 序列化的值
1.4.4 嵌套,针对:一对多,多对多的情况
from from rest_framework.serializers import ModelSerialize
from from rest_framework.serializers 

class 一对多类名(ModelSerializer):
    class Meta:
        model = 模型类名
        fields = [字段类名列表] | "__all__"#所有字段都返回

class 多对多类名(ModelSerializer):
    class Meta:
        model = 模型类名
        fields = [字段类名列表] | "__all__"#所有字段都返回
        
class 自定义ModelSerializer类名(ModelSerializer):
    一对多字段名 = 一对多类名()
    多对多字段名 = 多对多类名()
    class Meta:
        model = 模型类名
        fields = [字段类名列表]
1.4.5 继承
from from rest_framework.serializers import ModelSerialize
from from rest_framework.serializers 

class 继承类名(ModelSerializer):
    class Meta:
        model = 模型类名
        fields = [字段类名列表] | "__all__"#所有字段都返回
        
class 自定义ModelSerializer类名(ModelSerializer,继承类名):
    class Meta:
        model = 模型类名
        fields = [字段类名列表,可以添加自定义类名中的字段]

2. 序列化-源码流程

四、反序列化

1. 反序列化流程

路由-> 视图-> request.data ->校验(序列化器的类)->操作(数据库db,序列化器的类)

2. 数据校验

2.1数据校验是要在视图中校验的。但要在序列化类中写好校验规则。

from rest_framework.views import APIView
frrom rest_framework.response import Response
class 视图类名(APIView
    def post(self,request,*arg,**kwarg)
        1. 获取数据库的数据
        2. 数据校验
        	ser = 序列化类名(data = request.data)
            ser.is_valid()#返回的是True或False
        	业务编写
        		校验通过后,可以能完ser.validated_data获取校验后的数据,返回是OrderadDict数据集。
                校验失败后,可以能完ser.errors获取错误信息,返回字典{字段:[ErrorDetail(错误提示)]}
        3.返回JSON数据
        return Response(ser.data)
    
ser.is_valid(raise_exception=True)#成功可以利用值。抛出异常 raise ValidationError(self.errors)
注:不用判断,直接返回值,或返回错误值。

2.2序列化类校验规则

内置校验规则与正则校验规则

2.2.1内置校验规则

required = True | False 是否必须校验规则。

max_length = nu 最大长度

min_length = nu 最小长度

2.2.2 正则校验规则
var = serializers.CharField(validators=[RegesValidator(正则表达式,messege = "错误提示语!"),])
2.2.3 钩子函数
from rest_framework import serializer
from rest_framework import exceptions
#在序列化式子中编写
class 钩子函数类名(serilizers.Serializer):
    字段 = serializer.类型()
    ...
    def validate_字段名(self,value):
        业务逻辑
        #value是传过来的值
        raise exceptions.ValidationError("校验失败时,错误提示语!")
        return value#也可以改变相关的值,返回给ser.validated_data中相应字段值
    defm validate(self,attr):
        attr是ser.validated_data的值
        所有字段校验通过了,最后校验这个函数。
        raise excptions.ValidationError("全局钩子校验失败时提示语。")
        #返回为{"non_field_errors":[ErrorDetail(string='....',code='invalid')]}
        #api_setting.NON_FIELD_ERRORS_KEYF表示指定全局,错误提示语Key
        可以setting.py 中添加
        "NON_FIELD_ERRORS_KEYF":'字符串'
        return attr#也可以对attr中的字典数据进行操作
2.24 ModelSerializer校验规则
from rest_framework import serializer
from rest_framework import exceptions
#在序列化式子中编写
class 钩子函数类名(serilizers.ModelSerializer):
    class Meta:
        model = 数据库名
        fields = [字段列表] | "__all__"
        extra_keargs = {
            字段:{"validators":[RegexValidator(正则,messegs:"错误提示语")]},
            字段:{内置规则}如:{"max_length":50},
            ...
        }

在ModelSerializer中model对应的是数据库的字段,但不会把django模型中的限定语句加到序列化类中来,这时我们要自己加。可以用extra_kwargs={

字段:{…}

}

ModelSerializer的主要功能:

  • 可以简化模型字段与序列化字段的编写。
  • 可以将校验通过的数据,直接保存到数据库中。ser.save()
  • ser.save()有两个小问题(字段少了,字段多了)
    • 字段少了,可以在ser.save(少了的字段=value,…)
    • 字段多了,可以用ser.validated_data.pop(字段名)删除多余的字段数据。注:用pop删除后会返回删除的值。也可以用del ser.validated_data.get(字段名),用del 不返回值。
    • 用ser.save()是要序列化validated_data中的字段名与模型中的必存字段要一致。
    • ser没有使用save()时,ser.validated_data中没有id,但保存后就有了id。所以ser.data就可以序列化取值了。
2.2.5 字段属性(read_only,write_only)
  • read_only=Ture表示只序列化,不反序列化。
  • write_only=True表示只反序列化,不序列化。
  • 注:不能同时使用read_only、write_only。
  • 对于嵌套类时,也可以用read_only、write_only。
2.2.6对校验的总结

3.序列化字段与模型字段的总结

  • 序列化与模型取值这二个是独立的过程,模型取出的值后,再与序列化对接。序列化依据模型取出的数来进行操作,得到想要的结果。
  • 序列化时每一个字段依据模型取出的值操作来得到想要的结果。字段要与模型字段为依据来操作,就与source有关。注:默认source与序列化字段一致,特别指定时,可以不一样。为了得到想要的值就拓展了以下方法:
    • source=模型取值操作的方法一样
    • 自定义方法字段 = serailizes.SerializerMethodField()->def get_自定义方法字段(self,value)->返回就是JSON想要的结果。(注:默认read_only=True)
    • 嵌套类->使用时要关联模型类字段如:source=关联模型类字段
  • 反序列化与模型存值这二个是独立的过程,先获得前端传来的数据request.data.再校验->校验的过程,其实就是将取到的值与自身的校验规则是否合法,如果合法相应字段再与模型实例化,注模型实例化可以少字段。这就带来两个问题,反序列化的字段多了或少了。多了、少了都不能存入数据库中。所以要注意以下三个方面:
    • 多了要删除,可以看前面的(ModelSerializer的主要功能)
    • 少了要添加,可以看前面的(ModelSerializer的主要功能)
    • 保证ser.validated_data与模型中必存字段一致。

其实反序列化——>数据校验——>数据存储与模型数据存储是两个过程。它们只用ser.save()连结起来了。

3.1 对于chioces与序列化、反序列化、模型字段名一致

from collections import OrdereDict
from rest_framework.fields import SkipField
from rest_framework.relations import PKOnlyObject

class NbHookSerializer(object):
    def to_representation(self,instance):
        ret = OrderedDcit()
        fields = self._readable_fields
        
        for field in fields:
            if hasattr(self,"nb_%s"% field.field_name):
                value = getattr(self,'nb_%s'%field.field_name)(instance)
                ret[field.field_name] = value
            else:
                try:
                    attribute = field.get_attribute(instance)
                except SkipField:
                    continue
                check_for_none = attribute.pk if isinstance(attribute,PKOnlyObject) else attribute
                if check_for_none is None:
                    ret[field.field_name] = None
                else:
                    ret[field.field_name] = field.to_representation(attribute)
        return ret
            

使用时,可以用类的继承-在写序列化时使用。继承要注意,要写在先,因为类的继承优先级是先到后。

4. 数据校验-源码流程

五、模型查询的常规操作

  1. 对象.get_字段_display() #chioces显示后面的字段
  2. 对象.字段.字段#针对于一对多、多对多的情况
  3. filter(id__in=id列表)对于多个值的查询
  4. 对象添加值->对象.字段.set([id列表])#多对多的情况使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1581752.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3 +Taro 页面实现scroll-view 分页功能

需求 现在分页列表 后端只给你一个分页的数据列表 没有总页数 没有当前的分页 页数 只有这么一个list 、、、 如何去分页 我这使用的是scroll-view 组件 滑动到底部的事件 根据你当前设定的每页的数据数量和后端返回给你的数据列表数量 当某一次分页 两个数量不相等了以后 就…

ActiveMQ介绍及linux下安装ActiveMQ

ActiveMQ介绍 概述 ActiveMQ是Apache软件基金下的一个开源软件,它遵循JMS1.1规范(Java Message Service),是消息队列服务,是面向消息中间件(MOM)的最终实现,它为企业消息传递提供高…

目标检测——YOLO系列学习(一)YOLOv1

YOLO可以说是单阶段的目标检测方法的集大成之作,必学的经典论文,从准备面试的角度来学习一下yolo系列。 YOLOv1 1.RCNN系列回顾 RCNN系列,无论哪种算法,核心思路都是Region Proposal(定位) classifier&am…

DJI无人机二次开发:模拟航线飞行

1.下载大疆行业调参软件(大疆官网下载,有mac系统和win系统)。 2.安装软件以后用数据线连接电脑和无人机 3.识别无人机点击进去进入模拟器设置和遥控器相同的经纬坐标 4.在遥控器上载入航线 5.开始执行以后在上云api可以看到无人机在地图上移动…

目标检测——3D车道数据集

一、重要性及意义 3D车道检测在自动驾驶和智能交通领域具有极其重要的地位,其重要性和意义主要体现在以下几个方面: 首先,3D车道检测可以精确判断车辆在道路上的位置、方向和速度,从而预测潜在的危险情况并及时采取措施。这种能…

数据结构速成--数据结构和算法

由于是速成专题,因此内容不会十分全面,只会涵盖考试重点,各学校课程要求不同 ,大家可以按照考纲复习,不全面的内容,可以看一下小编主页数据结构初阶的内容,找到对应专题详细学习一下。 目录 一…

pdffactory pro 8注册码序列号下载 附教程

PdfFactory Pro可以说是一款行业专业且技术领先的的PDF虚拟打印机软件。其不仅占用系统内存小巧,功能强大,可支持用户无需使用Acrobat来创建Adobe PDF即可以进行PDF组件的创建和打印。同时,现在全新的PdfFactory Pro 8也正式上线来袭&#xf…

【资源分享】MAC上最好用的截图软件-Snipaste

::: block-1 “时问桫椤“是一个关注本科生到研究生教育阶段的不严肃的公众号,希望能在大家迷茫、难受、困难之时帮助到大家。用广大研究生的经验总结,让大家能尽早的适应研究生生活,尽快的看透科研本质。祝好!!&#…

Day94:云上攻防-云服务篇弹性计算云数据库实例元数据控制角色AK控制台接管

目录 云服务-弹性计算服务器-元数据&SSRF&AK 前提条件 利用环境1:获取某服务器权限后横向移动 利用环境2:某服务器上Web资产存在SSRF漏洞 云服务-云数据库-外部连接&权限提升 云上攻防-如何利用SSRF直接打穿云上内网 知识点&#xff1…

科技动态人工智能应用太空探索生物科技

根据最新的科技资讯,以下是一些值得关注的科技动态: 人工智能领域 智能体热潮 :随着大模型的研发热潮,AI智能体的发展迅速,它们被用作认知核心,具备强大的学习和迁移能力。智能体的架构和交互方式也在不断进…

vue快速入门(十五)监听键盘事件

注释很详细&#xff0c;直接上代码 上一篇 新增内容 特定按键监听事件全按键监听事件及两种判断方法 源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthde…

03-JAVA设计模式-代理模式详解

代理模式 什么是代理模式 Java代理模式是一种常用的设计模式&#xff0c;主要用于在不修改现有类代码的情况下&#xff0c;为该类添加一些新的功能或行为。代理模式涉及到一个代理类和一个被代理类&#xff08;也称为目标对象&#xff09;。代理类负责控制对目标对象的访问&a…

蓝桥杯简单STL

目录 vector vector定义 vector访问 常用函数 size() ​编辑 push_back(num) pop_back() clear 迭代器&#xff08;iterator) 迭代器定义 遍历数组示例 insert(it, element) erase(it) 标准模板库--STL&#xff0c;它包含了多种预定义的容器、算法和迭代器&…

算法——倍增

. - 力扣&#xff08;LeetCode&#xff09; 给你一棵树&#xff0c;树上有 n 个节点&#xff0c;按从 0 到 n-1 编号。树以父节点数组的形式给出&#xff0c;其中 parent[i] 是节点 i 的父节点。树的根节点是编号为 0 的节点。 树节点的第 k 个祖先节点是从该节点到根节点路径…

SQL注入sqli_libs靶场第一题

第一题 联合查询 1&#xff09;思路&#xff1a; 有回显值 1.判断有无注入点 2.猜解列名数量 3.判断回显点 4.利用注入点进行信息收集 爆用户权限&#xff0c;爆库&#xff0c;爆版本号 爆表&#xff0c;爆列&#xff0c;爆账号密码 2&#xff09;解题过程&#xff1…

【前端捉鬼记】使用nvm切换node版本后再用node -v查看仍然是原来的版本

今天遇到一个诡异的问题&#xff0c;使用nvm切换node版本&#xff0c;明明提示已经切换成功&#xff0c;可是再次查看node版本还是之前的&#xff01; 尝试了很多办法&#xff0c;比如重新打开一个cmd窗口、切换前执行nvm install version都没成功&#xff0c;直到找到这篇文章…

# ABAP SQL 字符串处理

经常我都要在ABAP的sql语句中对字符串进行处理&#xff0c;现在就总结一下可以用到的方法 文章目录 字符串处理拼接字段运行结果 填充字符串运行结果 截取字符串 SUBSTRING运行结果 CAST转换类型程序运行结果 字符串处理 在SQL语句中&#xff0c;有时候会有需要拼接字段或者是…

Java 集合Collection

集合的体系 Collection的结构体系 List系列集合&#xff1a;添加的元素是有序的、可重复、有索引。Set系列集合&#xff1a;无序、不重复、无索引 HashSet&#xff1a;无序、不重复、无索引LinkedHashSet:有序、不重复、无索引TreeSet&#xff1a;按照大小默认升序排序、不重复…

ES6基础(JavaScript基础)

本文用于检验学习效果&#xff0c;忘记知识就去文末的链接复习 1. ECMAScript介绍 ECMAScript是一种由Ecma国际&#xff08;前身为欧洲计算机制造商协会&#xff0c;英文名称是European Computer Manufacturers Association&#xff09;通过ECMA-262标准化的脚本程序设计语言…

SRNIC、选择性重传、伸缩性、连接扩展性、RoCEv2优化(六)

参考论文SRDMA&#xff08;A Scalable Architecture for RDMA NICs &#xff09;&#xff1a;https://download.csdn.net/download/zz2633105/89101822 借此&#xff0c;对论文内容总结、加以思考和额外猜想&#xff0c;如有侵权&#xff0c;请联系删除。 如有描述不当之处&…