• drf路由与认证


    1、路由

    ​ drf中可以通过继承视图基类ModelViewSet的路由写法,可以自动生成路由,从而优化继承视图类ViewSetMixin的路由

    ​ drf中不同路由的使用:

    1.1、urls.py中的基础路由

    url('book/',views.Bookview.as_view())
    url('book/(?P<pk>d+)',views.Bookdataview.as_view())
    

    1.2、继承ViewSetMixin视图类后的路由

    url('book'/,views.Bookview.as_view(action={'get':'list','post':'create'})),
    url('book/',views.Bookdataview.as_view(action={'get':'retrieve','put':'update','delete':'destroy'}))
    

    1.3、继承ModelViewSet视图类,优化之后的实现自动路由

    #1.导入routers模块
    from rest_framework.viewsets routers
    #2.实例化得到对象,二选一,DefaultRouter生成的路由比较多,不推荐使用
    route=router.DefaultRouter()
    route=router.SimpleRouter()
    #3.设置路由的url路径,以及路径触发视图层的对象
    router.register('books',view.Bookviewset)
    #4.将自动生成的url加入到原路由中
    urlpatterns+=router.urls
    

    2、action的使用

    ​ action是将已经继承了ModelViewSet视图类的自定义函数也添加到路由中,

    ​ 将装饰器放置在被装饰函数的上方,methods:请求方式,detail:是否带pk

    class Bookviewset(ModelViewSet):
    	queryset = Book.object.all()	
    	serializer_class = BookSerializer    #继承ModelVIESet,里面封装了各种的请求方式,通过url进行关联,内置了框架,需要设置数据库中的数据,以及设置序列化器
    	@action(methods=['GET','POST'],detail=True)#第一个为请求方式,可以在列表内放置多个,第二个为是否需要<pk>值
    	def get_1(self,request,pk):   #访问时路径为url('book/(?P<pk>[^/.]+)/get_1$'),即必须要提交pk以及get_1
    		book=self.get_queryset()[:2]		#自定义,取前两个值
    		ser = self.get_serializer(book,many=True)
    		return Response(ser.data)
    	
    

    3、认证

    3.1、认证的写法

    ​ 先写一个类,继承BaseAuthentication,类里面重写函数authenticate,认证的逻辑写在里面,

    ​ 认证成功,返回两个值,其中给一个值赋给Request的对象user,

    ​ 认证失败,则抛出异常:APIEception或者AuthenticationFailed

    3.2、认证源码分析

    #1 APIVIew----》dispatch方法---》self.initial(request, *args, **kwargs)---->有认证,权限,频率
    #2 只读认证源码: self.perform_authentication(request)
    #3 self.perform_authentication(request)就一句话:request.user,需要去drf的Request对象中找user属性(方法) 
    #4 Request类中的user方法,刚开始来,没有_user,走 self._authenticate()
    
    #5 核心,就是Request类的 _authenticate(self):
        def _authenticate(self):
            # 遍历拿到一个个认证器,进行认证
            # self.authenticators配置的一堆认证类产生的认证类对象组成的 list
            #self.authenticators 你在视图类中配置的一个个的认证类:authentication_classes=[认证类1,认证类2],对象的列表
            for authenticator in self.authenticators:
                try:
                    # 认证器(对象)调用认证方法authenticate(认证类对象self, request请求对象)
                    # 返回值:登陆的用户与认证的信息组成的 tuple
                    # 该方法被try包裹,代表该方法会抛异常,抛异常就代表认证失败
                    user_auth_tuple = authenticator.authenticate(self) #注意这self是request对象
                except exceptions.APIException:
                    self._not_authenticated()
                    raise
    
                # 返回值的处理
                if user_auth_tuple is not None:
                    self._authenticator = authenticator
                    # 如何有返回值,就将 登陆用户 与 登陆认证 分别保存到 request.user、request.auth
                    self.user, self.auth = user_auth_tuple
                    return
            # 如果返回值user_auth_tuple为空,代表认证通过,但是没有 登陆用户 与 登陆认证信息,代表游客
            self._not_authenticated()
    

    3.3、认证组件的使用

    ​ 先新建一个文件:app_auth.py,里面建立一个认证类,继承BaseAuthentication,

    ​ 建立函数authenticate,认证就是确定token是否存在,在视图层views中建立了登录函数 ,里面有产生一个随机的token,从前端取到token的值判断它是否存在,再判断它是否存在数据库内,如果存在的话返回给用户信息,以及token,用来放行该用户

    from rest_framework.authentication import BaseAuthentication
    from rest_framework.exceptions import AuthenticationFailed
    from app01.models import UserToken
    class MyAuthentication(BaseAuthentication):
    	def authenticate(self,request):
    		token=request.GET.get('token')
    		if token:
    			user_token = UserToken.objects.filter(token=token).first()
    			if user_token:
    				return user_token.user,token
    			else:
    				raise AuthenticationFailed('认证失败')
    		else:
    			raise AuthenticationFailed('请求地址中需要携带token')
    

    4、认证功能全局和局部的使用

    4.1、全局使用

    ​ 在setting中配置

    REST_FRAMEWORK={
        "DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",]
    }
    

    4.2、局部使用

    ​ 在视图类中写

    authentication_classes=[MyAuthentication]
    

    4.3、局部禁用

    ​ 在视图类前添加空,优先查找自身的属性

    authentication_classes=[]
    
  • 相关阅读:
    mysql无法启动ERROR! MySQL is running but PID file could not be found ?
    mybatis返回list很智能很简答的,只需要配置resultmap进行类型转换,你dao方法直接写返回值list<对应的object>就行了啊
    mybatis resultmap标签type属性什么意思
    python学习笔记——第三章 串
    POJ 2485:Highways(最小生成树&amp;&amp;prim)
    G-Sensor 校准标准
    Unity3D 4.x 使用Mecanim实现动画控制
    quartz群调查调度机制和源代码分析
    什么是你的七个核心竞争力-弱点让你闪
    poj 3368 Frequent values(段树)
  • 原文地址:https://www.cnblogs.com/jingpeng/p/13276722.html
Copyright © 2020-2023  润新知