• DAY 71 drf09


    1 分页
    -list数据
    -基本分页()
    -偏移分页
    -游标分页
    -写一个类:重写类中几个属性
    -配置在继承了ListApiView视图类
      pagination_class = MyCursorPagination
    -配置在setting中
       
    2 继承APIView实现分页

    3 前端后台模板
    -Xadmin:基于layui写的一个后台管理模板,便于大家快速搭建后台管理
    -layui也有一套后台管理
    -bootstrap:后台管理自己搭建(bbs的后台管理)
    -admin lte
       
    -django的admin继续写
    -xadmin:bootstrap+jq   ---基本上废弃
    -simple ui:vue+emelentui      ---比较友好
       
    -前后端分离项目
      -iview
          -vue-admin
       
      -第三方的模块,包
    -把它下载下来,放到自己项目中,作为项目的一部分
      -而不用pip install的方式
           
    4 RBAC
    -基于角色的访问控制
    -后台管理(公司内部,分部门)
    -三个表:用户表,角色表(组表,部门表),权限表
    -用户和角色的多对多
    -角色和权限的多对多
    -用户和权限多对多

    继承了APIView实现分页

    class BookView(APIView):
       def get(self, request):
           qs = models.Book.objects.all()
           # page_obj = PageNumberPagination()
           page_obj = LimitOffsetPagination()
           # 每页显示两条
           # page_obj.page_size = 2
           # page_obj.page_size_query_param = 'size'
           # page_obj.max_page_size = 5
           
           page_obj.default_limit=2
           # 得到的就是当前页码的数据
           page_res = page_obj.paginate_queryset(qs, request, self)
           print(page_res)
           ser = serializer.BookModelSerializer(instance=page_res, many=True)

           # return Response({'status': 100, 'msg': '查询成功', 'data': ser.data, 'next': page_obj.get_next_link(),
           return page_obj.get_paginated_response(ser.data)

    1 jwt 原理分析

    1 token:
       -加密的串:有三段
      -头.荷载(数据).签名
         -eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
       -使用bsse64转码
       -第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).

    1.2 drf+jwt开发流程

    """
    1)用账号密码访问登录接口,登录接口逻辑中调用 签发token 算法,得到token,返回给客户端,客户端自己存到cookies中

    2)校验token的算法应该写在认证类中(在认证类中调用),全局配置给认证组件,所有视图类请求,都会进行认证校验,所以请求带了token,就会反解出user对象,在视图类中用request.user就能访问登录的用户

    注:登录接口需要做 认证 + 权限 两个局部禁用
    """

     

    2 base64的使用

    1 加码和解码
    # base64转码跟语言无关,任何语言都能编码,解码base64
    import base64
    import json
    dic = {'id': 1, 'name': 'lqz'}

    str_dic=json.dumps(dic)
    print(str_dic)

    # base64加码
    res=base64.b64encode(str_dic.encode('utf-8'))
    print(res)


    ## 解码
    # res=base64.b64decode(b'eyJpZCI6IDEsICJuYW1lIjogImxxeiJ9')
    # res=base64.b64decode(b'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9')
    # res=base64.b64decode(b'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9')

    print(res)

    2.1 自动签发token和自动认证

    1 借助于djangorestframework-jwt实现
    pip3 install djangorestframework-jwt
    2 默认用的是auth的user表
    3 不需要写登录功能了
    4 也不需要写认证类了
    5 djangorestframework-jwt也有配置文件,也有默认配置
    默认过期时间是5分钟
    import datetime
    JWT_AUTH = {
       # 过期时间1天
       'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
       # 自定义认证结果:见下方序列化user和自定义response
    # 如果不自定义,返回的格式是固定的,只有token字段
       'JWT_RESPONSE_PAYLOAD_HANDLER': 'users.utils.jwt_response_payload_handler',  
    }

     

    ###登录功能
    路由(登录功能,djangorestframework-jwt已经写好了登录):
    path('login/', obtain_jwt_token),

    ###限制某个接口必须登录才能用(加载视图类中)
    from rest_framework_jwt.authentication import JSONWebTokenAuthentication
    from rest_framework.permissions import IsAuthenticated
    authentication_classes = [JSONWebTokenAuthentication,]
    permission_classes = [IsAuthenticated,]

    ##如果只加了JSONWebTokenAuthentication,登录可以用,不登录也可以用
    ##请求路径(需要在请求头中带)
    # Authorization: jwt asdfasdfasfasdfasdtoken串
    http://127.0.0.1:8000/api/books/   get请求
         

     

    3 jwt自动签发token,自定义响应格式

    # 写一个函数
    def response_user_login(token, user=None, request=None):
       print(request.method)
       return {
           'status':100,
           'msg':'登录成功',
           'username':user.username,
           'token':token
      }
    #在配置文件中配置
    JWT_AUTH = {

       'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.response.response_user_login',
    }

     

    4 jwt手动签发token

    4.1 自己定义的user表,自己写登录功能

    class UserLoginViwe(APIView):

    def post(self, request, *args, **kwargs):
    username = request.data.get('username')
    password = request.data.get('password')

    user = models.User.objects.filter(username=username, password=password).first()
    if user:
    #签发token
    payload = jwt_payload_handler(user)
    token=jwt_encode_handler(payload)
    return Response({'status':100,'msg':'登录成功','token':token})
    else:
    return Response({'status':101,'msg':'用户名或密码错误'})

    4.2 自定义认证类

    import jwt
    from rest_framework import exceptions
    from rest_framework.authentication import BaseAuthentication
    from rest_framework_jwt.authentication import JSONWebTokenAuthentication
    from rest_framework_jwt.settings import api_settings
    jwt_decode_handler = api_settings.JWT_DECODE_HANDLER

    from app01 import models
    class JsonAuthentication(JSONWebTokenAuthentication):
    def authenticate(self, request):
    jwt_value=self.get_jwt_value(request)
    # jwt_value=request.GET.get('token')
    #验证签名,验证是否过期

    try:
    # 得到荷载
    payload = jwt_decode_handler(jwt_value)
    print(payload)
    # user=models.User.objects.filter(id=payload['user_id']).first()

    #效率更高一写,不需要查数据库了
    user=models.User(id=payload['user_id'],username=payload['username'])
    # user={'id':payload['user_id'],'username':payload['username']}
    except jwt.ExpiredSignature:
    msg = 'token过期'
    raise exceptions.AuthenticationFailed(msg)
    except jwt.DecodeError:
    msg = '签名错误'
    raise exceptions.AuthenticationFailed(msg)
    except jwt.InvalidTokenError:
    raise exceptions.AuthenticationFailed('反正就不对')

    # 这个咱么不能用,因为它找的是auth的user表,我们是去自己表中查,这个我们需要自己写
    # user = self.authenticate_credentials(payload)
    # models.User.objects.filter(username=)

    return (user, jwt_value)

     

    5 Vue快速使用

    1 vue:就是一个js框架,跟jq很像
    2 cdn,下载到本地,script中引入
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

    <body>
    <div id="app">

    {{ message }}
    <br>
    <h1>{{ name }}</h1>
    </div>

    </body>

    <script>
    //el:指的是被vue接管的div,以后再操作这个div,都是通过vue操作
    var app = new Vue({
    el: '#app',
    data: {
    message: 'Hello world!',
    name:'lqz'
    }
    })
    </script>
    </html>
  • 相关阅读:
    洛谷P1613 跑路
    洛谷P2149 Elaxia的路线
    洛谷P3119 草鉴定
    洛谷P1972 HH的项链
    洛谷P2458 保安站岗
    uva10061
    uva579
    uva 127 "Accordian" Patience
    uva10177 (2/3/4)-D Sqr/Rects/Cubes/Boxes?
    uva156
  • 原文地址:https://www.cnblogs.com/DEJAVU888/p/14893792.html
Copyright © 2020-2023  润新知