drf过滤、分页、全局异常处理
一 过滤Filtering
详细链接:
http://www.xuexianqi.top/archives/584.html
对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。
|
|
在配置文件中增加过滤后端的设置:
|
|
在视图中添加filter_fields属性,指定可以过滤的字段
|
|
二 排序
对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。
使用方法:
在类视图中设置filter_backends,使用rest_framework.filters.OrderingFilter
过滤器,REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,则按照ordering参数指明的排序字段对数据集进行排序。
前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。
示例:
|
|
如果需要在过滤以后再次进行排序,则需要两者结合!
|
|
三 分页Pagination
REST framework提供了分页的支持。
我们可以在配置文件中设置全局的分页方式,如:
|
|
也可通过自定义Pagination类,来为视图添加不同分页行为。在视图中通过pagination_clas
属性来指明。
|
|
注意:如果在视图内关闭分页功能,只需在视图内设置
|
|
可选分页器
1) PageNumberPagination
前端访问网址形式:
|
|
可以在子类中定义的属性:
- page_size 每页数目
- page_query_param 前端发送的页数关键字名,默认为”page”
- page_size_query_param 前端发送的每页数目关键字名,默认为None
- max_page_size 前端最多能设置的每页数量
|
|
2)LimitOffsetPagination
前端访问网址形式:
|
|
可以在子类中定义的属性:
- default_limit 默认限制,默认值与
PAGE_SIZE
设置一直 - limit_query_param limit参数名,默认’limit’
- offset_query_param offset参数名,默认’offset’
- max_limit 最大limit限制,默认None
|
|
3)CursorPagination
前端访问网址形式:
|
|
可以在子类中定义的属性:
- cursor_query_param:默认查询字段,不需要修改
- page_size:每页数目
- ordering:按什么排序,需要指定
|
|
应用
|
|
分页器三种如何使用
1 内置了三种分页器 -PageNumberPagination:普通分页 -LimitOffsetPagination:偏移分页 -CursorPagination:游标分页 2 APIView和GenericAPIView+ListModelMixin 3 GenericAPIView+ListModelMixin的分页模式 4 PageNumberPagination:普通分页(用的最多) -page_size = api_settings.PAGE_SIZE # 每页显示多少条 -page_query_param = 'page' # 查询参数 -page_size_query_param = size # 查询的时候指定每页显示多少条 -max_page_size = 10 # 每页最多显示多少条 -使用方式: -定义一个类,继承PageNumberPagination -重写四个属性 -在继承了GenericAPIView+ListModelMixin视图类中配置 pagination_class = MyPageNumberPagination -查询 http://127.0.0.1:8000/students/?page=1&size=5 5 LimitOffsetPagination:偏移分页 -default_limit = api_settings.PAGE_SIZE # 默认条数 -limit_query_param = 'limit' # 查询时,指定查询多少条 -offset_query_param = 'offset' # 查询时,指定的起始位置是哪 -max_limit = None # 查询时,最多返回多少条 -使用方式: -定义一个类,继承LimitOffsetPagination -重写四个属性 -在继承了GenericAPIView+ListModelMixin视图类中配置 pagination_class = MyPageNumberPagination -查询 http://127.0.0.1:8000/students/?limit=100&offset=1 6 CursorPagination:游标分页(速度块) -cursor_query_param = 'cursor' # 查询的时候,指定的查询方式 -page_size = api_settings.PAGE_SIZE # 每页显示多少条 -ordering = '-created' # 排序方式 -page_size_query_param = size # 查询的时候指定每页显示多少条 -max_page_size = None #每页最多显示多少条 -使用方式: -定义一个类,继承LimitOffsetPagination -重写四个属性 -在继承了GenericAPIView+ListModelMixin视图类中配置 pagination_class = MyPageNumberPagination -查询 http://127.0.0.1:8000/students/?limit=100&offset=1 7 APIView的分页模式 -新建一个类,继承普通分页,重写四个属性 -视图类写法如下 class StudentApiView(APIView): def get(self,request): student_list=Student.objects.all() page=MyPageNumberPagination()# 实例化得到对象 # 只需要换不同的分页类即可 res=page.paginate_queryset(student_list,request,self)# 开始分页 ser=StudentSerializer(res,many=True) return page.get_paginated_response(ser.data) # 返回数据
源码理解:
https://www.cnblogs.com/Franciszw/p/13341191.html#6%E8%BF%87%E6%BB%A4%E6%8E%92%E5%BA%8F%E5%88%86%E9%A1%B5%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E6%8E%A5%E5%8F%A3%E6%96%87%E6%A1%A3
四 异常处理 Exceptions
REST framework提供了异常处理,我们可以自定义异常处理函数。
4.1 使用方式
|
|
在配置文件中声明自定义的异常处理
|
|
如果未声明,会采用默认的方式,如下
rest_frame/settings.py
|
|
4.2 案例
补充上处理关于数据库的异常
|
|
4.3 REST framework定义的异常
- APIException 所有异常的父类
- ParseError 解析错误
- AuthenticationFailed 认证失败
- NotAuthenticated 尚未认证
- PermissionDenied 权限决绝
- NotFound 未找到
- MethodNotAllowed 请求方式不支持
- NotAcceptable 要获取的数据格式不支持
- Throttled 超过限流次数
- ValidationError 校验失败
也就是说,很多的没有在上面列出来的异常,就需要我们在自定义异常中自己处理了。
自动生成接口文档
1 借助于第三方:coreapi,swagger
2 在路由中
from rest_framework.documentation import include_docs_urls
path('docs/', include_docs_urls(title='图书管理系统api'))
3 在配置文件中
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}
4 写视图类(需要加注释)
class BookListCreateView(ListCreateAPIView):
"""
get:
返回所有图书信息.
asdfasfda
post:
新建图书.
"""
queryset = Student.objects.all()
serializer_class = StudentSerializer
5 只需要在浏览器输入,就可以看到自动生成的接口文档()
http://127.0.0.1:8000/docs/
drf过滤源码解析
https://daimajiaoliu.com/daima/47240473f9003e8
全局异常
1 统一接口的返回方式,即便视图函数执行出错
2 使用方式
-写一个函数
def common_exception_handler(exc, context):
response = exception_handler(exc, context)
if response is None:
response = Response({'code':999,'detail': '未知错误'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return response
-在setting中配置
REST_FRAMEWORK = {
'EXCEPTION_HANDLER':'app01.utils.common_exception_handler'
}