过滤
# django内置的过滤器
from rest_framework.generics import GenericAPIView
from app01.serializer import BookSerializer
from rest_framework.filters import SearchFilter
from rest_framework.generics import ListAPIView
class Bookview(ListAPIView,GenericAPIView):
filter_backends = [SearchFilter, ]
search_fields = ('title',)
queryset = models.Book.objects.all()
serializer_class = BookSerializer
# 查询的时候是模糊查询
# 必须是 search=...
http://127.0.0.1:8000/Bookview/?search=斗
# 第三方过滤模块 和排序可以一起使用
# -pip3 install django-filter :最新版本(2.4.0)要跟django2.2以上搭配
from rest_framework.generics import ListAPIView
from django_filters.rest_framework import DjangoFilterBackend
class Bookview(ListAPIView,GenericAPIView):
# filterset_fields 中表字段一定要存在
filter_backends = [DjangoFilterBackend, ]
filterset_fields = ('title',)
"""
### 过滤后再排序
-在视图类中配置
filter_backends = [OrderingFilter,DjangoFilterBackend]
ordering_fields = ('id', 'age')
filter_fields=['name','age']
-查询的时候
http://127.0.0.1:8000/students/?name=lqz&age=19&ordering=-age,-id
"""
queryset = models.Book.objects.all()
serializer_class = BookSerializer
# 查询的时候
http://127.0.0.1:8000/Bookview/?title=斗破苍穹
分页的三种方式
第一种 普通分页
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
class CommonPageNumberPagination(PageNumberPagination): # 普通分页(用的最多)
page_size = 3 # 每页默认显示多少条
page_query_param = 'page' # 查询参数 page=第几页
page_size_query_param = 'size' # 查询的时候指定每页显示多少条 size=5 最大不会超过这个 max_page_size = 10
max_page_size = 10 # 查询最大条数
# http://127.0.0.1:8000/Bookview/?page=1&size=4 page=1 查询第一页 size=4 显示四条 如果不写 page_size = 3
# http://127.0.0.1:8000/Bookview/?page=1 如果不写 size 默认使用 page_size = 3
class Bookview(ListAPIView, GenericAPIView):
pagination_class = ConnomPageNumberPagination # 因为分页方式只能选择一种 所以不能是列表
queryset = models.Book.objects.all()
serializer_class = BookSerializer
第二种 偏移分页
class CommonLimitOffsetPagination(LimitOffsetPagination):
default_limit = 2 # 每页显示多少条 不写的就相当于是默认值
limit_query_param = 'limit' # 每页显示的查询条数 ?limit=10 不写默认写多少条就是多少条
offset_query_param = 'offset' # 偏移量 从第二条开始 拿五条 http://127.0.0.1:8000/Bookview/?offset=2&limit=5
max_limit = 5 # 最大查询数量
class Bookview(ListAPIView, GenericAPIView):
pagination_class = ConnomLimitOffsetPagination # 因为分页方式只能选择一种 所以不能是列表
queryset = models.Book.objects.all()
serializer_class = BookSerializer
第三种 游标分页
class CommonCursorPagination(CursorPagination):
cursor_query_param = 'cursor' # 按游标查询的游标分页 ?cursor=xxx
page_size = 3 # 每页显示多少条
ordering = 'id' # 排序规则 必须是表中字段
# 这种方式 只能上一页 下一页 ?cursor=cj0xJnA9NA%3D%3D 是随机生成的
# http://127.0.0.1:8000/Bookview/
# http://127.0.0.1:8000/Bookview/?cursor=cj0xJnA9NA%3D%3D
class Bookview(ListAPIView, GenericAPIView):
pagination_class = CommonCursorPagination # 因为分页方式只能选择一种 所以不能是列表
queryset = models.Book.objects.all()
serializer_class = BookSerializer
基于APIview 写分页
class CommonPageNumberPagination(PageNumberPagination): # 普通分页(用的最多)
page_size = 3 # 每页默认显示多少条
page_query_param = 'page' # 查询参数 page=第几页
page_size_query_param = 'size' # 查询的时候指定每页显示多少条 size=5 最大不会超过这个 max_page_size = 10
max_page_size = 10 # 查询最大条数
class ListpageApixiew(APIView):
def get(self,request):
book = models.Book.objects.all() # 获取所有数据
page = CommonPageNumberPagination() # 实例化得到一个对象
# 只需要配置不同的分页类即可
# 调用父类的属性
res = page.paginate_queryset(book,request,self)# 开始分页
ser = BookSerializer(instance=res,many=True)
return page.get_paginated_response(ser.data) # 返回数据
# http://127.0.0.1:8000/ListpageApixiew/?page=2 参数跟分页类中的一样
全局异常
1 读APIView源码时,即是三大认证和视图类的方法中出现了异常,都会被try捕获,做全局异常处理
2 捕获到,统一处理,处理成固定格式—》给前端是统一的
{code:100,msg:成功,result:[{},{}]}
3 无论是否出异常,给前端格式都是统一的
{code:100,msg:成功}
# 3 只要三大认证或视图类的方法出了异常,就会走这个函数
# - 1 新建py文件,写一个函数,在函数中处理异常
from rest_framework.views import exception_handler
from rest_framework.response import Response
def common_exception_handler(exc, context):
# exc是错误类型 context是当次请求的request view视图对象
res = exception_handler(exc, context) # drf的异常,处理了
if res: # 有值说明是drf的异常, 是drf的异常
# data = {'detail': exc.detail}
# return Response(data)
# {code: 100, msg: 成功}
detail = res.data.get('detail') or "drf异常,请联系系统管理员"
return Response({'code': 999, 'msg': detail})
else: # 如果没值,说明是自己的异常
return Response({'code': 888, 'msg': '系统异常,请联系系统管理员:%s'%str(exc)})
# 配置文件 记得配置
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app01.auth_class.common_exception_handler'
}