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=[]  # 表示禁用认证。
    
    
  • 相关阅读:
    美剧字幕美国怪谭第一季第4集
    ios 中生成随机数
    美剧字幕绿箭侠第一季第1集
    关于iOS6应用中第三方类库不支持armv7s的问题解决
    美剧字幕美国怪谭第一季第2集
    美剧字幕美国怪谭第一季第一集
    美剧字幕美国怪谭第一季第3集
    NewWords/1100
    Developing for App StorePreparing the Development Team03
    平静(转载)
  • 原文地址:https://www.cnblogs.com/liqianxin/p/13275452.html
Copyright © 2011-2022 走看看