zoukankan      html  css  js  c++  java
  • drf-路由和认证

    drf-路由

    1 路由

    针对视图集ViewSet,我们出来可以自己手动指明请求方式与执行函数间的对应关系,还可以使用Routers来快速实现路由信息

    Rest-framework提供了两个router:SimpleRouter和DefaultRouter。前者较为简洁,后者产生路由相对较多。

    1.1 路由router的使用

    路由的配置有三种方式:

    # 1 在urls中配置
        url(r'^books/(?P<pk>d+)', views.BookView.as_view(),
        url(r'^books/', views.BooksView.as_view(),
        
    # 2 继承了ViewSetMixin,路由就需要指定对应关系
        url(r'^books/(?P<pk>d+)', views.BookView.as_view(actions={'get':'retrieve', 'put':'update','delete':'destroy'})),
        url(r'^books/', views.BooksView.as_view(actions={'get':'list', 'post':'create'}))
            
    # 3 继承视图类ModelViewSet,路由可以自动生成
        urls.py
            # 第一步:导入routers模块
                from rest)framework import routers
            # 第二步:有两个类,实例化得到对象
                routers.DefaultRouter  生成的路由更多
                routers.SimpleRouter  有两个路由
            # 第三步:注册 router.register('前缀','视图集类','别名')
                router.register('books',views.BookViewSet)
            # 第四步:拼接到原路由中
                urlpatterns += router.urls
    

    1.2 action的使用

    action可以给继承子ModelViewSet的视图类中定义的函数也添加路由

    from rest_fromwork.decorates import action
    
    class BookView(ModelViewSet):
        queryset=Book.objects.all()
        serializer_class = BookSerializer
        
        @action(methods=['get'], detail=True)
        def get_1(self, request):
            book = self.get_queryset()[:2]
            ser = self.get_serializer(book, many=True)
            return Response(ser.data)
        
    methods中传入的时列表,列表中放的是请求方式。
    detail:布尔类型,决定是否在路由中带pk值
        True:xxx/<pk>/action方法名/
        False:xxx/action方法名
        当需要使用pk的时候就设置为True,否则就设置为False
    

    2 认证

    2.1 认证的写法

    实现认证的步骤:

    1. 写一个类,继承BaseAuthentication,重写authenticate,认证的逻辑卸载里卖弄,认证通过,返回两个值,一个值给了request对象的user,一个给了request对象的auth。认证失败的话,就抛出异常
    2. 全部使用和局部使用

    2.2 源码分析

    认证、权限、频率的执行代码都是在APIView》dispatch方法》self.initial(request,*args,**kwargs) 中的try下。

    '''
    self.perform_authentication(request)为认证源码,内部就只有一句:request.user。需要去drf中Request对象中找user属性。
    查找发现,user是一个方法。
    '''
        @property
        def user(self):
            if not hasattr(self, '_user'):  # 刚开始并没有_user
                with wrap_attributeerrors():
                    self._authenticate()  # 执行这个
            return self._user
    
        # 要点
        def _authenticate(self):
            # 遍历拿到self.authenticators认证器对象中一个个验证器进行验证
            # authentication_classes=[认证类1,认证类2]
            for authenticator in self.authenticators:
                try:
                    # 认证方法authenticate(self,request)
                    # 返回值:登录的用户与认证的信息组成的tuple
                    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()
    
    

    2.3 认证组件的使用

    # 写一个认证类app_auth.py
    from rest_framework.authemtication import BaseAuthentication
    from rest_framework.exceptions import AuthenticationFailed
    from app01.models import UserToken
    
    class Authentication_app(BaseAuthentication):
        def authenticate(self, request):
            token = request.GET.get('token')
            if token:
                user_token = UserToken.objects.fiter(token=token).first()
                if user_token:
                    return user_token.user, token
                else:
                    raise AuthenticationFailed('认证失败')
            else:
                raise AuthenticationFailed('不含有token')
                
    
    # 全局使用和局部使用
        # 全局使用
            REST_FRAMEWORK={
        "DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.Authentication_app",]
    }
        # 局部使用,在视图类上写
            authentication_classes=[MyAuthentication]
            authentication_classes=[]  # 表示禁用认证。
    
    
  • 相关阅读:
    CodeForces 492C Vanya and Exams (贪心)
    CodeForces 492A Vanya and Cubes
    如何设置 Windows 默认命令行窗口大小和缓冲区大小
    [MySQL] Data too long for column 'title' at row 1
    [转] Hibernate不能自动建表解决办法(hibernate.hbm2ddl.auto) (tables doesn't exist)
    CodeForces 489D Unbearable Controversy of Being (不知咋分类 思维题吧)
    Autofac官方文档翻译--二、解析服务--1解析参数传递
    Autofac官方文档翻译--一、注册组件--4组件扫描
    Autofac官方文档翻译--一、注册组件--3属性和方法注入
    Autofac官方文档翻译--一、注册组件--2传递注册参数
  • 原文地址:https://www.cnblogs.com/liqianxin/p/13275452.html
Copyright © 2011-2022 走看看