三种分页方式
# 什么样接口要分页----》获取所有 # 三种分页方式---》继承GenericAPIView,ListModelMixin -list方法---》
分页的使用 page.py
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination # 基本分页:正常的查第几页,每页显示多少条的方式---》常用 class CommonPageNumberPagination(PageNumberPagination): #4 个类属性 page_size = 2 #每页显示条数 page_query_param = 'page' # 查询页码参数 ?page=10 page_size_query_param = 'size' # ?page=3&size=5000 max_page_size = 5 #可以通过size控制每页显示的条数,但是通过这个参数控制最多显示多少条 # http://127.0.0.1:8000/books/?page=1&size=300000 # 偏移分页 class CommonLimitOffsetPagination(LimitOffsetPagination): default_limit = 2 # 每页显示多少条 limit_query_param = 'limit' # 取多少条 offset_query_param = 'offset' #从第0个位置偏移多少开始取数据 max_limit = 5 # 最大限制条数 # offset=6&limit=90000 # http://127.0.0.1:8000/books/?limit=3&offset=3 # 从第三条开始取3条 # limit_query_description = _('Number of results to return per page.') # 游标分页---》针对于大数据量分页效率高---》可控性差--->只能选择上一页和下一页,不能直接跳转到某一个 class CommonCursorPagination(CursorPagination): cursor_query_param = 'cursor' # 查询的名字 等同于 page=xx page_size = 3 # 每页显示多少条 ordering = 'id' # 排序规则,必须是表中有的字段,一般用id #http://127.0.0.1:8000/books/?cursor=cD0z
views.py
from rest_framework.generics import GenericAPIView from rest_framework.viewsets import GenericViewSet from rest_framework.mixins import ListModelMixin from .models import Book from .serializer import BookSerializer # 三种分页方式: from .page import CommonPageNumberPagination as PageNumberPagination from .page import CommonLimitOffsetPagination from .page import CommonCursorPagination class BookView(GenericAPIView,ListModelMixin): class BookView(GenericViewSet, ListModelMixin): queryset = Book.objects.all() serializer_class = BookSerializer pagination_class= CommonCursorPagination
继承APIView实现分页
# APIView实现分页 from rest_framework.views import APIView from rest_framework.viewsets import ViewSet from rest_framework.response import Response class BookView(ViewSet): def list(self,request): books=Book.objects.all() # 分页 # paginator=PageNumberPagination() paginator=CommonLimitOffsetPagination() #分页过后的数据 qs=paginator.paginate_queryset(books,request,self) #序列化 ser=BookSerializer(qs,many=True) # 第一种方式:每页总条数,上一页,下一页 # return Response(ser.data) # 第二种:自己凑 # return Response({ # 'count':books.count(), # 'next': paginator.get_next_link(), # 'previous':paginator.get_previous_link(), # 'results': ser.data # }) # 第三种;直接使用分页类的方法 return paginator.get_paginated_response(ser.data)
JWT原理
# jwt:Json web token # cookie,session,token -cookie是存放在客户端浏览器的键值对 -session是存放在服务端的键值对 客户端:sessionId:asdfasdf----》放到cookie中 服务端: asdfasdf:{id:3,name:lqz} dddddd:{id:4,name:pyy} -token: 字符串:分三段 -第一段:头--》公司信息,加密方式。。。 -第二段:荷载--》放用户信息---->{id:3,name:lqz} -第三段:签名---》把第一段和第二段通过某种加密方式+秘钥加密得到一个字符串 asdfads -把三段使用base64编码后拼到一起 dasfasd.asdfasdasd.asdfads -【token 的签发】---》登录成功后,服务端生成 -把token串给前端---》前端拿着 -后面前端只要发请求,就携带token串到后端 -【token的验证】--》拿到第一段和第二段使用同样的加密方式+秘钥再加密---》得到字符串跟第三段比较,如果一样,表示没有被篡改,如果不一样,表明被篡改了,token不能用了 -如果没有被篡改,取出第二段 当前登录用户的信息 id #jwt:Json web token---》只针对于web方向的token方式验证 # token典型样子 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ # jwt组成 -1 header---》{'typ': 'JWT','alg': 'HS256'}---》通过bas64编码后----》eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 -2 payload---》荷载---》真正用户的数据 { "sub": "1234567890", # 过期时间 "id":3 "name": "John Doe", "admin": true } -3 signature---》签名 header (base64后的) payload (base64后的) secret # base64的编码和解码 -base64的长度一定是4的倍数,如果不到用=补齐 import json import base64 # d={'typ': 'JWT','alg': 'HS256'} # s=json.dumps(d) # print(s) #把字符串进行b64编码 # res=base64.b64encode(bytes(s,encoding='utf-8')) # print(res) #把b64编码的字符串,解码 # b=b'eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJIUzI1NiJ9' # res=base64.b64decode(b) # print(res) # 开发中使用jwt认证的重点 -签发token---》登录 -认证token---》认证类
Django中快速使用JWT
# https://github.com/jpadilla/django-rest-framework-jwt # https://github.com/jazzband/djangorestframework-simplejwt # 用法95%相似 #安装 pip3 install djangorestframework-jwt # 快速使用---》使用的表是django的auth的user表---》创建一个用户 # 只需要在路由中配置---》auth的user表中有用户 from rest_framework_jwt.views import obtain_jwt_token urlpatterns = [ path('login/', obtain_jwt_token), ]
修改返回格式
# 登录成功返回格式:{code:100,msg:"登录成功",token:asdfasdf,username:lqz} # 写一个函数,在配置文件配置 def jwt_response_payload_handler(token, user=None, request=None): return {'code': 100, 'msg': '登陆成功', 'token': token, 'username': user.username} # 配置文件配置 JWT_AUTH = { 'JWT_RESPONSE_PAYLOAD_HANDLER': 'app01.utils.jwt_response_payload_handler', }
JWT的验证
# 只需要在视图类中加入一个认证类,一个权限类 class BookView(ViewSet): # 认证类 authentication_classes = [JSONWebTokenAuthentication,] # 权限类 permission_classes = [IsAuthenticated,] # 需要在请求头中携带token -请求头中key:Authorization -请求头的value值:jwt 空格 token串
自定义用户表签发Token
自己定义用户表,实现签发Token功能----登录接口 from rest_framework_jwt.settings import api_settings jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER from rest_framework.decorators import action class UserView(ViewSet): @action(methods=['POST'],detail=False) def login(self, request): username = request.data.get('username') password = request.data.get('password') user = UserInfo.objects.filter(username=username, password=password).first() if user: # 登录成功---》签发token payload = jwt_payload_handler(user) # 根据当前登录用户获取荷载 print(payload) token = jwt_encode_handler(payload) # 根据荷载生成token return Response({'code': 100, 'msg': '登录成功', 'token': token}) else: return Response({'code': 101, 'msg': '用户名或密码错误'})
自定义认证类验证Token
from rest_framework_jwt.settings import api_settings from rest_framework import exceptions from .models import UserInfo jwt_decode_handler = api_settings.JWT_DECODE_HANDLER jwt_get_username_from_payload = api_settings.JWT_PAYLOAD_GET_USERNAME_HANDLER class LoginAuth(BaseAuthentication): def authenticate(self, request): # 1 取出 token jwt_value = request.META.get('HTTP_TOKEN') # 2 验证token是否合法 # try: # payload = jwt_decode_handler(jwt_value) # except jwt.ExpiredSignature: # msg = 'token过期了' # raise exceptions.AuthenticationFailed(msg) # except jwt.DecodeError: # msg = 'token解码错误' # raise exceptions.AuthenticationFailed(msg) # except jwt.InvalidTokenError: # msg = '解析token未知错误' # raise exceptions.AuthenticationFailed(msg) try: payload = jwt_decode_handler(jwt_value) except Exception: raise exceptions.AuthenticationFailed('token错误') print(payload) # 荷载---》user_id user = UserInfo.objects.filter(pk=payload['user_id']).first() return user, jwt_value
标签:自定义,JWT,jwt,token,---,Token,import,page From: https://www.cnblogs.com/wql0817/p/16617510.html