首页 > 其他分享 >drf学习-7

drf学习-7

时间:2022-10-09 19:35:29浏览次数:45  
标签:鸭子 get self request 视图 学习 user drf

一、内容回顾

1、drf路由的使用

  路由有三种写法

    -视图类.as_view

    -视图类.as_view({'get':'list'})

    -自动生成路由

      导入——实例化——注册——加入到urlpatterns

      类有两个:SimpleRouter,DefaultRouter

      加入到urlpatterns的两种方式:列表加操作,include

  路由的第二种和第三种写法:视图类必须继承ViewSetMixin——重写了类方法as_view

  要自动生成:其实自动生成的是定死的   {'get':'list','post':'create','delete':'destroy','put':'update','get':'retrieve'}

  如果你完全自动生成路由,视图类必须有:list,create,destory,update,retrieve这些方法

  如果可以继承ViewSetMixin+GenericAPIView+5个视图扩展类

  继承ViewSetMixin+9个视图子类

 视图类中的其他方法必须使用action装饰器来装饰,才能自动生成路由

/user/login

@action(methods=['post','get'],detail=False,url_path='login')

2、视图类

  APIView:所有东西都需要自己写,get,post。。。

  GenericAPIView:(以后要跟表模型打交道就需要继承它)

    -必须要配置两个类属性,要序列化的数据,序列化类

    -get.post

    -self.get_queryset()

    -self.get_serializer()
    -self.get_object()

  5个视图扩展类:要配合GenericAPIView就可以完成5个接口的写法

        ListModelMixin:list
        CreateModelMixin:create
        DestroyModelMixin:destroy
        RetrieveModelMixin:retrieve
        UpdateModelMixin:update

  9个视图子类:GenericAPIView+5个视图扩展类的组合+写个请求方式的某个方法

    	ListAPIView:get
        CreateAPIView:post
        
        UpdateAPIView:put
        RetrieveAPIView:get
       	DestroyAPIView :delete
        
        ListCreateAPIView:get,post
        
        RetrieveUpdateDestroyAPIView:put,get,delete
        RetrieveDestroyAPIView:get,delete
        RetrieveUpdateAPIView:get,put

  视图集

	   -ViewSetMixin:路由写法变成了第二种或第三种
        -ViewSet:ViewSetMixin+APIView
        -GenericViewSet:ViewSetMixin+GenericAPIView
        -ModelViewSet:GenericViewSet+5个视图扩展类
	   -ReadOnlyModelViewSet:GenericViewSet+2个视图扩展类

如果不跟数据库(表模型)打交道:就继承APIView

如果想自动生成路由(路由写法变了),就继承ViewSetMixin

3.登录接口

  表模型:User:用户信息,UserToken:用户登录信息

  用户向/user/login/发送post请求,携带用户名密码——自动生成路由+action装饰器

  用户登录了要有记录,只要登录成功,就在UserToken表中记录一下

    如果之前有过记录,就要更新,如果没有记录,就是新增

  随机字符串的生成:uuid

  登录成功返回给前端{code:100,msg:登陆成功,token:随机字符串}

4、验证用户是否登录

  写一个认证类:继承BaseAuthenticaion

  重写def authenticate(self,request)方法

  在方法内部判断用户是否登录

    自己定的规则,用户携带token在哪

    如果token放在了请求头中,应该从哪取?——reques.META

      http请求头的数据从request.META中取

      统一取:HTTP_请求头大写

    通过token判断用户是否登录:表中查,能查到就是登录了,查不到就是没登录

    如果登录了就返回两个值,一个是当前登录用户,一个是token

    如果没有登录,直接抛AuthenticationFailed

  认证类写好,使用

    -局部使用:视图类中

    -全局使用:配置文件中

    -局部禁用:视图类中设置为空列表

二、内容详细

注意

django的配置文件不要乱导入,乱导入可能会出错
'''
django的运行是在加载完配置文件后才能运行
因为模块的导入会执行那个模块,而这个模块中又有别的导入,别的导入必须djagno运行起来才能使用
'''

1、权限类使用

认证:校验用户是否登录,登录认证

用户登录了,某个接口可能只有超级管理员才能访问,普通用户不能访问,出版社的所有接口,必须登录而且是超级管理员才能访问

使用步骤;

  1. 写一个类,继承BasePermission
  2. 重写has_permission方法
  3. 在方法中校验用户是否有权限(request.user就是当前登录用户)
  4. 如果有权限,返回True,没有权限,返回False
  5. self.message是给前端的提示信息
  6. 局部使用,全局使用,局部禁用
from rest_framework.permissions import BasePermission
class UserTypePermission(BasePermission):
    def has_permission(self,request,view)
       # 只有超级管理员有权限
       if request.user.user_type == '1':
            return True  # 有权限
        else:
            # self。message = '普通用户和小用户都没有权限' 返回给前端的提示是什么样
            # 用了choice后,user.user_type拿到的是数字类型,想变成字符串user.get_user_type_display()
            # self.message = '您是: %s 用户,您没有权限'%request.user.get_user_type_display()
            return False  # 没有权限

2、频率类使用

无论是否登录和是否有权限,都要限制访问的频率,比如一分钟只能访问3次

使用步骤:

  1. 写一个类:继承SimpleRateThrottle
  2. 重写get_cache_key,返回唯一的字符串,会以这个字符串做频率限制
  3. 写一个类属性scop='随意些',必须要跟配置文件对象
  4. 配置文件中写
        ‘DEFAULT_THROTTLE_RATES’:{
    
          ‘随意写’:‘3/m’  # 3/h  3/s  3/d
    
    }
  5. 局部配置,全局配置,局部禁用
from rest_framework,throttling import BaseThrottle,SimpleRateThrottle
class MyThrottling(SimpleRateThrottle):  # 我们继承SimpleRateThrottle去写,而不是继承BaseThrottle去写
    # 类属性,这个类属性可以随意命名,但是要跟配置文件对应
    scope = 'luffy'
    def get_cache_key(self,request,view):
        # 返回什么,频率就以什么做限制
        # 可以通过用户id限制
        # 可以通过ip地址限制
        return request.META.get('REMOTE_ADDR')
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES':['app01.throttling.MyThrottling'],
    'DEFAULT_THROTTLE_RATES': {
        'luffy': '3/m'
    }
}

3、认证源码分析

写个认证类,重写某个方法,配置在视图类上,就有认证了——认证类加了,在视图类的方法中,request.user就是当前登录用户——猜认证类的执行,是在视图类的方法之前执行的

源码分析

之前咱们读APIView的执行流程——包装了新的request,执行了3大认证,执行视图类的方法,处理了全局异常

-入口:APIView的dispatch

-APIView的dispatch的496行上下:self.initial(request,*args,**kwargs)

-APIView的initial

-413行上下:有三句话,分别是:认证,权限,频率

self.perform_authentication(request)

self.check_permissions(request)

self.check_throttles(request)

读认证类的源码——APIView的perform_authentication(request),315行上下

def perform_authentication(self,request):
    request.user  # 新的request

request是新的request——Request类中找user属性(方法),是个方法包装成了数据属性

来到Request类中找:220行

def user(self):
    if not hasattr(self,'_user'):  # Request类的对象中反射_user
        with wrap_attributeerrors():
            self._authenticate()  # 第一次会走这个代码
    return self._user
-Request的self._authenticate()——373行
    def _authenticate(self):
        for authenticator in self.authenticators:  # 配置在视图中所有的认证类的对象
            try:
                # (user_token.user,token)
                user_auth_tuple = authenticator.authenticate(self)
            # 调用认证类对象的authenticate
        except exceptions.APIException:
            self.__not__authenticated()
            raise
            
        if user_auth_tuple is not None:
            self._authenticator = authenticator # 忽略
            self.user,self.auth = user_auth_tuple #解压赋值
            return
        # 认证类可以配置多个,但是如果有一个返回了两个值,后续的就不执行啦
   self.__not__authenticated()

 总结:

  认证类。要重写authenticate方法,认证通过返回两个值或None,认证不通过抛AuthenticationFailed(继承了APIException)异常

4、权限源码分析

先读最简单的权限执行流程——APIView的check_permissions(request),325行上下

def check_permissions(self,request):
    for permission in self.get_permissions():
          # permission是咱们配置在视图类中权限类的对象,对象调用它的绑定方法has_permission
            # 对象调用自己的绑定方法会把自己传入(权限类的对象,request,视图类的对象)
            if not permission.has_permission(request, self):
                self.permission_denied(
                    request,
                    message=getattr(permission, 'message', None),
                    code=getattr(permission, 'code', None)
                )
                
   -APIVIew的self.get_permissions(),273行上下
	return [permission() for permission in self.permission_classes]
   -self.permission_classes 就是咱们在视图类中配的权限类的列表
   -所以这个get_permissions返回的是 咱们在视图类中配的权限类的对象列表[UserTypePermession(),]

 5、频率类源码

     -之前咱们读APIView的执行流程---》包装了新的request,执行了3大认证,执行视图类的方法,处理了全局异常

-APIView的check_throttles:351上下
def check_throttles(self, request):
    throttle_durations = []
    for throttle in self.get_throttles():
        if not throttle.allow_request(request, self):
            throttle_durations.append(throttle.wait())

 总结:

  要写频率类,必须重写allow_request方法,返回True(没有到频率的限制)或False(到了频率的限制)

 6、鸭子类型

 走路像鸭子,说话像鸭子,他就是鸭子(low!!!)

指的是面向对象中,子类不需要显示的继承某个类,只有某个的方法和属性,那我就属于这个类

 

假设有个鸭子类Duck类,有两个方法,run,speak方法

假设又有一个普通鸭子类,PPDuck,如果它也是鸭子,它需要继承DUCK类,只要继承了鸭子类,什么都不需要写,普通鸭子类的对象就是鸭子这种类型,如果不继承,普通鸭子类的对象就不是鸭子这种类型

 假设又有一个唐老鸭子类,TDuck,如果它也是鸭子,它需要继承Duck类,只要继承了鸭子类,什么都不需要写,唐老鸭子类的对象就是鸭子这种类型;如果不继承,唐老鸭子类的对象就不是鸭子这种类型

 

但是

python不推崇这个,他推崇鸭子类型,指的是

不需要显示的继承某个类,只要我的类中有run和speak方法,我就是鸭子这个类

如果使用python鸭子类型的写法,如果方法写错了,他就不是这个类型了,会有问题

python为了解决这个问题:

  方式1:abc模块,装饰后,必须重写方法,不重写就报错

  方式2:drf源码中使用的:父类中写这个方法,但没有具体实现,直接抛异常!!

标签:鸭子,get,self,request,视图,学习,user,drf
From: https://www.cnblogs.com/zzjjpp/p/16772211.html

相关文章

  • 【2022-10-09】DRF从入门到入土(七)
    drf组件之权限类使用#认证:校验用户是否登录,登录认证#用户登录了,某个接口可能只有超级管理员才能访问,普通用户不能访问#出版社的所有接口,必须登录,而且是超级管理员才......
  • 计算机本科如何制定学习计划,给自己安排上
    写在前边:本文适合刚入学的大一新生,或者大二学生,如果想做计算机这一行,如果没有方向,可以看看这篇文章。当然了,对于更优秀的人,如果看到了,希望能给我更好的建议,目前我是大三下。......
  • 推荐一个今天误入的 源码学习网站
    今天想查看一下 spring data JPA 的源码,然后看到一个不错的源码学习网站。 链接地址:​​http://www.iocoder.cn/Spring-Data-JPA/good-collection/​​......
  • drf三大认证(认证,权限,频率)及其源码分析
    drf三大认证之认证drf三大认证之权限drf三大认证之频率drf三大认证之认证源码分析drf三大认证之权限源码分析鸭子类型drf三大认证之认证  访问接......
  • Python学习路程——Day09
    Python学习路程——Day09文件操作1、文件的概念''' 操作系统为了使用户更好的使用计算机,而创建的一个快捷方式。 双击一个文件,相当于把硬盘的数据资源加载到内存中。......
  • 2022-2023-1 20221313《计算机基础与程序设计》第六周学习总结
    2022-2023-120221313《计算机基础与程序设计》第六周学习总结作业信息这个作业属于哪个课程<班级的链接>https://edu.cnblogs.com/campus/besti/2022-2023-1-CFAP......
  • drf -三大权限认证例子
    三大权限认证测试例子代码models.pyfromdjango.dbimportmodels#Createyourmodelshere.classBook(models.Model):name=models.CharField(max_length=3......
  • drf之权限类与频率类
    一、权限类#权限就是我们在登入之后我们在访问这个接口的时候有没有访问的权限#eg:现在我们把用户等级分为两个等级,一个为vip用户,一个为普通用户然......
  • 【博学谷学习记录】超强总结,用心分享 。多线程相关点知识学习。
    一、实现多线程1.1了解多线程多线程是指从软件或硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提......
  • 2022-2023-1 20221414《计算机基础和程序设计》第六周学习总结
    2022-2023-120221414《计算机基础和程序设计》第六周学习总结教材内容总结Polya解决问题:0.自顶而下1.理解问题(用提问来把问题搞明白)2.找到联系(寻找熟悉模型和把问......