过滤类,分页类源码分析

过滤类源码

  1. 查询所有才涉及到过滤(视图类必须继承:ListModelMixin+GenericAPIView)
  2. 在视图类中配置:
    filter_backends=['过滤类']
  3. 执行过滤类中的:filter_queryset方法,在方法中完成过滤,排序
  4. 查询所有>执行的是get>list(ListModelMixin)
  5. ListModelMixin==>list方法
    queryset = self.filter_queryset(self.get_queryset())# 执行过滤
  6. 视图类的GenericAPIView的:self.filter_queryset
    def filter_queryset(self, queryset): for backend in list(self.filter_backends): queryset = backend().filter_queryset(self.request, queryset, self) return queryset
  7. 自定义的过滤类,重写filter_queryset方法完成过滤==>配置在视图类中,就可以执行

分页类源码

  1. 查询所有才涉及到分页(视图类必须继承:ListModelMixin+GenericAPIView)
  2. 在视图类中配置:
    pagination_class = '分页类'
  3. 查询所有>执行的是get>list(ListModelMixin)
  4. ListModelMixin==>list方法
    page = self.paginate_queryset(queryset) # 执行分页 if page is not None: # 如果使用了分页 serializer = self.get_serializer(page, many=True)#只序列化当前分页的数据 return self.get_paginated_response(serializer.data)# 上一页和下一页和总条数
  5. 视图类GenericAPIView中:self.paginate_queryset(queryset)
    # self.paginator是在视图类中配置的分页类的对象 # 实现了分页功能,取出从前端地址中传入的,第几页,取多少条 # 在该方法中自动实现分页,返回当前页码的数据 return self.paginator.paginate_queryset(queryset, self.request, view=self)
  6. 视图类GenericAPIView中:get_paginated_response(serializer.data)
    # self.paginator是在视图类中配置的分页类的对象 self.paginator.get_paginated_response(data)

继承APIView,实现分页

  1. 配置好分页类 page.py
    from rest_framework.pagination import PageNumberPagination class MyPageNumberPagination(PageNumberPagination): page_size = 2 page_query_param = 'page' page_size_query_param = 'size' max_page_size = 5
  2. 建立表模型 models.py
    from django.db import models # Create your models here. class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=5,decimal_places=2) sales = models.IntegerField()
  3. 创建序列化器 serializer.py
    from rest_framework import serializers from app01.models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__'
  4. 视图 views.py
    class BookView(APIView): def get(self, request): book_list = Book.objects.all() # 分页,通过分页类分页 page = MyPageNumberPagination() # 实例化得到分页类对象,不需要传参数 # 对book_list进行分页,分页类对象page的某个方法,来实现对book_list的分页 # 返回的res是列表,是当前页码的所有数据 res = page.paginate_queryset(book_list, request, self) # 对当前页码的数据,进行序列化 ser = BookSerializer(instance=res, many=True) return page.get_paginated_response(ser.data)

手动写分页

class MyPage():
def paginate_queryset(self, qs, request):
# 获取当前在哪一页
page = int(request.GET.get('page'))
count = 3 # 每页显示条数

return qs[(page - 1) * count:count]


JWT介绍

JWT的起源与介绍

​ ​

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

是一种前后端的登录认证方式,它分token的签发和认证,签发的意思是用户登录成功,生成三段式的token串;认证指的是用户访问某个接口,需要携带token串过来,我们完成认证。

JWT的构成

三段式:

  • header:一般放公司信息,加密方式
  • payload:存放用户信息(user_id,username,email,expire)
  • signatue:第一部分和第二部分加密得到的

通过base64转码,用点分割,类似于这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ


base64编码

base64编码不是加密,是一种转码格式,它的编码的长度都是4的倍数,如果不是4的倍数需要用等号补齐,因为是4的倍数,最多只有三个等号。

解码

import base64
s = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
res = base64.b64decode(s)
print(res)


编码

import base64
dic = {'name':jesse, 'age':18}
# 编码字符串,json格式字符串
res = base64.b64encode(json.dump(dic).encode('utf-8'))
print(res)


JWT的快速使用

需要使用第三方模块:

djangorestframework-jwt


各个公司使用的可能不一样,由于django-rest-framework-jwt的作者已经很长时间不维护该模块,可能会有使用djangorestframework-simplejwt。

安装

pip3 install djangorestframework-jwt


签发token给前端

  • 用户表使用auth的user表
  • 登录功能不用写,djangorestframework-jwt已经写好了

JWT内置认证类的使用

签发(直接使用内置的)

在路由中配置:

from django.contrib import admin
from django.urls import path
from app01 import views
from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
path('admin/', admin.site.urls),
path('login/', obtain_jwt_token) # 内置的登录模块,可以签发token,依赖auth的user表
]


由于以来auth_user表,我们需要创建一个用户:

python3 manage.py createsuperuser


创建好用户之后发送登录请求,就会签发token:

过滤类 分页类源码 APIView实现分页 JWT认证_分页

认证

from rest_framework_jwt.authentication import JSONWebTokenAuthentication  # drf_jwt内置的认证类
from rest_framework.permissions import IsAuthenticated
class BookView(APIView):
# 使用drf_jwt内置的认证,必须加这两个
authentication_classes = [JSONWebTokenAuthentication, ]
permission_classes = [IsAuthenticated]


需要注意的是用postman发送请求的时候,需要在请求头里发送

'Authorization':jwt token字符串  # 格式必须这样传 day72


过滤类 分页类源码 APIView实现分页 JWT认证_分页_02