前言:全局配置(配置文件配置)、局部配置(view视图函数内配置)
一、过滤
针对获取列表资源接口(对视图函数self.list
的查询集进行过滤);
首先,需要安装第三方扩展包pip install django-filter
其次,注册子应用,配置过滤后端
INSTALLED_APP = [
# ....
'django_filters',
]
# REST_FRAMEWORK配置项对"drf接口"进行全局配置
# 全局配置针对所有的drf视图(接口)
REST_FRAMEWORK = {
# ......
# 过滤后端,针对所有资源视图的self.list接口(获取列表数据),进行过滤动作
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
)
}
视图函数接口配置过滤:
- 1.1、指定字段过滤
# 针对当前视图,定义过滤的依据字段
filterset_fields = ['bread', 'btitle', 'bcomment']
注意:每个字段是并列关系(and与关系)
- 1.2、排序过滤
# 定义排序依据字段
# GET + /books/?ordering=bread 升序
# GET + /books/?ordering=-bread 降序
ordering_fields = ['bread', 'bcomment', 'bpub_date']
二、分页
针对获取列表资源接口(对视图函数self.list
的查询集进行分页)
2.0、两种分页器逻辑
-
(1)、
PageNumberPagination
: 按照每页pagesize
条数据划分,取第page
页GET + /books/?page=1&pagesize=5
: 按照5条数据每页划分,要第1页
-
(2)、
LimitOffsetPagination
: 从第1条数据开始,偏移offset
条数据,取limit
条数据
1、全局配置
# REST_FRAMEWORK配置项对"drf接口"进行全局配置
# 全局配置针对所有的drf视图(接口)
REST_FRAMEWORK = {
# ......
# 分页后端
# 1、 PageNumberPagination: 按照每页pagesize个划分,取第page页
# 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
# 'PAGE_SIZE': 3 # 后端定义默认每页数目
# 2、 LimitOffsetPagination: 根据偏移offset个数据,取limit条数据
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
}
2、局部配置(效果和全局配置一样)
# pagination_class = PageNumberPagination
pagination_class = LimitOffsetPagination
GET http://api.example.org/books/?page=4
GET http://api.example.org/books/?limit=100&offset=400
3、自定义分页器后端(局部配置自定义)
在视图函数中自定义两种分页器MyPageNum
和MyLimitOffset
class MyPageNum(PageNumberPagination):
# 约定:/books/?page=1&pagesize=5
# 通过类属性,定义查询字符串参数
page_query_param = 'page' # 指定查询字符串参数key为'page',传递取第几页
page_size_query_param = 'pagesize' # 指定查询字符串参数key为'pagesize',传递每页数目
page_size = 5 # 指定后端默认按照每页几个划分
max_page_size = 10 # 每页数目的最大值
class MyLimitOffset(LimitOffsetPagination):
# 约定:/books/?offset=5&limit=2
# 通过类属性,定义查询字符串参数
limit_query_param = 'limit'
offset_query_param = 'offset'
default_limit = 5
max_limit = 10
class HerosView(ModelViewSet):
queryset = HeroInfo.objects.all()
serializer_class = HeroInfoModelSerializer
# 自定义分页后端(分页器),一般需要自定义分页器的时候,可以采用局部配置
# pagination_class = MyPageNum
pagination_class = MyLimitOffset
三、自定义分页的响应结果
需求:加入分页器之后,视图的响应结果由分页器构造的;不一定符合业务需求,所以我们需要去改写分页器返回的结果;
(1)、定位到分页结果构造函数
GenericAPIView里面的get_paginated_response
控制了分页返回的结果;- 分页器中的
get_paginated_response
函数控制了分页返回的结果;
(2)、改写!
-
第一种方案:重写资源视图中
get_paginated_response
函数实现自定义分页;但是,只能够作用于当前资源视图;class HerosView(ModelViewSet): queryset = HeroInfo.objects.all() serializer_class = HeroInfoModelSerializer # 自定义分页后端(分页器),一般需要自定义分页器的时候,可以采用局部配置 pagination_class = MyPageNum # 重写GenericAPIView函数实现自定义分页返回结果(只作用于当前资源视图) def get_paginated_response(self, data): # 构造响应结果 # data:查询集分页子集序列化的结果 # 返回响应对象 return Response(data={ 'code': 0, 'errmsg': 'ok', 'lists': data })
-
第二种方案:重写分页器中的
get_paginated_response
函数实现自定义分页;只要资源视图采用该分页器,那么自定义分页结果就起效果;class MyPageNum(PageNumberPagination): # 约定:/books/?page=1&pagesize=5 # 通过类属性,定义查询字符串参数 page_query_param = 'page' # 指定查询字符串参数key为'page',传递取第几页 page_size_query_param = 'pagesize' # 指定查询字符串参数key为'pagesize',传递每页数目 page_size = 5 # 指定后端默认按照每页几个划分 max_page_size = 10 # 每页数目的最大值 # 重写分页器中该函数,作用于所有使用当前分页器的资源视图 def get_paginated_response(self, data): return Response(data={ 'code': 0, 'errmsg': 'ok', 'lists': data }) class HerosView(ModelViewSet): queryset = HeroInfo.objects.all() serializer_class = HeroInfoModelSerializer # 自定义分页后端(分页器),一般需要自定义分页器的时候,可以采用局部配置 pagination_class = MyPageNum
-
改写响应格式后的返回页面: