偏移分页-游标(加密)分页-自定义过滤器-第三方过滤器插件(django-filter)
目录
复习
"""
1、drf-jwt签发与校验源码
签发token的请求 - 登录请求 - ObtainJSONWebToken - post - 将账号密码丢给序列化类处理 - 得到user、token => 序列化类的全局钩子
要访问需要认证的视图类 - 访问前需要通过认证组件与权限组件的校验 - jwt认证和是否登录权限 - 给认证组件提供带有token请求头的请求,将token解析出user,返回 (user, token) => drf-jwt框架的jwt认证组件的认证方法
2、多方式登录(手动签发)
简单:从request拿账号密码 - 数据库查询得到user - payload - token - 返回
复杂:
视图:将账号密码等信息丢该序列化类 - 从序列化对象中拿user、token - 返回
序列化:定义字段接收要反序列化的数据 - 全局钩子校验数据得到user,并签发token - user、token保存在实例化对象中
3、自定义jwt认证规则(手动校验)
实现:自定义认证类,继承BaseJSONWebTokenAuthentication - 自定义token反爬小策略,从请求头中获取并抛出设置的盐后的token
前提:群查接口
4、搜索组件
1)视图类:filter_backends = [SearchFilter]
2)视图类:search_fields = ['name', 'price']
3)接口:/cars/?search=... | eg: /cars/?search=1
5、排序组件
1)视图类:filter_backends = [OrderingFilter]
2)视图类:search_fields = ['pk', 'price']
3)接口:/cars/?ordering=... | eg: /cars/?ordering=-price,pk
6、基础分页组件
1)自定义分页类继承drf分页类,将必要参数赋值
2)视图类: pagination_class = pagenations.MyPageNumberPagination
3)接口:/cars/
"""
drf偏移分页组件
pahenations.py
from rest_framework.pagination import LimitOffsetPagination
class MyLimitOffsetPagination(LimitOffsetPagination):
# ?offset=从头偏移的条数&limit=要显示的条数
limit_query_param = 'limit'
offset_query_param = 'offset'
# ?不传offset和limit默认显示前3条,只设置offset就是从偏移位往后再显示3条
default_limit = 3
# ?limit可以自定义一页显示的最大条数
max_limit = 5
# 只使用limit结合ordering可以实现排行前几或后几
# ?ordering=-price&limit=2 => 价格前2
views.py
from rest_framework.generics import ListAPIView
class CarListAPIView(ListAPIView):
# 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
pagination_class = pagenations.MyLimitOffsetPagination
drf游标分页组件(了解)
pahenations.py
# 注:必须基于排序规则下进行分页
# 1)如果接口配置了OrderingFilter过滤器,那么url中必须传ordering
# 1)如果接口没有配置OrderingFilter过滤器,一定要在分页类中声明ordering按某个字段进行默认排序
from rest_framework.pagination import CursorPagination
class MyCursorPagination(CursorPagination):
cursor_query_param = 'cursor'
page_size = 3
page_size_query_param = 'page_size'
max_page_size = 5
ordering = '-pk'
views.py
from rest_framework.generics import ListAPIView
class CarListAPIView(ListAPIView):
# 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
pagination_class = pagenations.MyCursorPagination
自定义过滤器
filters.py
# 自定义过滤器,接口:?limit=显示的条数
class LimitFilter:
def filter_queryset(self, request, queryset, view):
# 前台固定用 ?limit=... 传递过滤参数
limit = request.query_params.get('limit')
if limit:
limit = int(limit)
return queryset[:limit]
return queryset
views.py
from rest_framework.generics import ListAPIView
class CarListAPIView(ListAPIView):
# 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
filter_backends = [LimitFilter]
过滤器插件:django-filter
安装
>: pip3 install django-filter
过滤条件层:自定义api/filters.py
# django-filter插件过滤器类
from django_filters.rest_framework.filterset import FilterSet
from . import models
# 自定义过滤字段
from django_filters import filters
class CarFilterSet(FilterSet):
min_price = filters.NumberFilter(field_name='price', lookup_expr='gte')
max_price = filters.NumberFilter(field_name='price', lookup_expr='lte')
class Meta:
model = models.Car
fields = ['brand', 'min_price', 'max_price']
# brand是model中存在的字段,一般都是可以用于分组的字段
# min_price、max_price是自定义字段,需要自己自定义过滤条件
视图层:views.py
# django-filter插件过滤器
from django_filters.rest_framework import DjangoFilterBackend
from .filters import CarFilterSet
class CarListAPIView(ListAPIView):
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
filter_backends = [DjangoFilterBackend]
# django-filter过滤器插件使用
filter_class = CarFilterSet
# 接口:?brand=...&min_price=...&max_price=...
# eg:?brand=宝马&min_price=5&max_price=10 => 5~10间的宝马牌汽车