zoukankan      html  css  js  c++  java
  • 路由、认证

    ## 1 路由

    ```python
    # 1 在urls.py中配置
    path('books4/', views.Book4View.as_view()),
    re_path('books4/(?P<pk>d+)', views.Book4DetailView.as_view()),
    # 2 一旦视图类,继承了ViewSetMixin,路由
    path('books5/', views.Book5View.as_view(actions={'get':'list','post':'create'})), #当路径匹配,又是get请求,会执行Book5View的list方法
    re_path('books5/(?P<pk>d+)', views.Book5View.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),

    # 3 继承自视图类,ModelViewSet的路由写法(自动生成路由)
    -urls.py
    # 第一步:导入routers模块
    from rest_framework import routers
    # 第二步:有两个类,实例化得到对象
    # routers.DefaultRouter 生成的路由更多
    # routers.SimpleRouter
    router=routers.DefaultRouter()
    # 第三步:注册
    # router.register('前缀','继承自ModelViewSet视图类','别名')
    router.register('books',views.BookViewSet) # 不要加斜杠了

    # 第四步
    # router.urls # 自动生成的路由,加入到原路由中
    # print(router.urls)
    # urlpatterns+=router.urls
    '''
    -views.py
    from rest_framework.viewsets import ModelViewSet
    from app01.models import Book
    from app01.ser import BookSerializer
    class BookViewSet(ModelViewSet):
    queryset =Book.objects
    serializer_class = BookSerializer
    ```

    ### 1.1 action的使用

    ```python
    # action干什么用?为了给继承自ModelViewSet的视图类中定义的函数也添加路由
    # 使用
    class BookViewSet(ModelViewSet):
    queryset =Book.objects.all()
    serializer_class = BookSerializer
    # methods第一个参数,传一个列表,列表中放请求方式,
    # ^books/get_1/$ [name='book-get-1'] 当向这个地址发送get请求,会执行下面的函数
    # detail:布尔类型 如果是True
    #^books/(?P<pk>[^/.]+)/get_1/$ [name='book-get-1']
    @action(methods=['GET','POST'],detail=True)
    def get_1(self,request,pk):
    print(pk)
    book=self.get_queryset()[:2] # 从0开始截取一条
    ser=self.get_serializer(book,many=True)
    return Response(ser.data)

    # 装饰器,放在被装饰的函数上方,method:请求方式,detail:是否带pk
    ```

    ## 2 认证

    ### 2.1 认证的写法

    ```python
    # 认证的实现
    1 写一个类,继承BaseAuthentication,重写authenticate,认证的逻辑写在里面,认证通过,返回两个值,一个值最终给了Requet对象的user,认证失败,抛异常:APIException或者AuthenticationFailed
    2 全局使用,局部使用
    ```

    ### 2.2 认证的源码分析

    ```python
    #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()
    ```

    ### 2.3 认证组件的使用

    ```python
    # 写一个认证类 app_auth.py
    from rest_framework.authentication import BaseAuthentication
    from rest_framework.exceptions import AuthenticationFailed
    from app01.models import UserToken
    class MyAuthentication(BaseAuthentication):
    def authenticate(self, request):
    # 认证逻辑,如果认证通过,返回两个值
    #如果认证失败,抛出AuthenticationFailed异常
    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')

    # 可以有多个认证,从左到右依次执行
    # 全局使用,在setting.py中配置
    REST_FRAMEWORK={
    "DEFAULT_AUTHENTICATION_CLASSES":["app01.app_auth.MyAuthentication",]
    }
    # 局部使用,在视图类上写
    authentication_classes=[MyAuthentication]
    # 局部禁用
    authentication_classes=[]
    ```
  • 相关阅读:
    CSS之EM相对单位
    html之canvas
    JS之事件监听
    html之iframe
    [转]nodejs中的process模块--child_process.exec
    [转]阮一峰:理解RESTful架构
    JS性能之滚动条之外的其他部分
    JS性能之setTimeout与clearTimeout
    CSS禁止鼠标事件---pointer-events:none
    打开文件、文件操作、管理上下文
  • 原文地址:https://www.cnblogs.com/0B0S/p/13617954.html
Copyright © 2011-2022 走看看