Django-8-搜索、排序、分页

1、在项目的settings.py文件中的REST_FRAMEWORK 字典修改DRF配置信息

# 修改DRF配置信息
REST_FRAMEWORK = {
  ...# d.指定后端使用的渲染器
    # 会自动根据请求头中的Accept字段来,返回前端需要的数据格式
    # 请求头中默认如果未添加Accept字段参数,那么会返回application/json
    # 默认如果指定了Accept字段为text/html,那么会返回可浏览的API页面
    'DEFAULT_RENDERER_CLASSES': [
        # 会返回json
        'rest_framework.renderers.JSONRenderer',
        # 会返回可浏览的API页面
        'rest_framework.renderers.BrowsableAPIRenderer',
    ],

    # a.指定使用的全局过滤引擎
    # b.所有继承GenericAPIView的类视图中获取列表数据的接口,支持过滤功能
    # c.前端在过滤时,默认需要使用search作为查询字符串参数的名称,可以使用SEARCH_PARAM进行修改
    'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.SearchFilter', 'rest_framework.filters.OrderingFilter'],
    # 'SEARCH_PARAM': 'se',

    # a.指定分页引擎类
    # 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'DEFAULT_PAGINATION_CLASS': 'utils.pagination.PageNumberPagination',  # 可以自己指定路径拓展PageNumberPagination类的功能
  # b.必须指定每一页显示的最大数据条数 

  'PAGE_SIZE': 4, }

 

2、view.py文件中指定过滤字段

搜索关键字默认search,如果要搜索多个条件,用空格分隔

eg:

 

 

    """在类视图中指定过滤引擎,优先级高于全局"""
    filter_backends = [SearchFilter, OrderingFilter]
"""
    搜索:
    - search_fields指定对模型类中哪些字段进行搜索过滤
    - 可以在字段前面添加前缀
            '^': 'istartswith',以[搜索字符]开头
            '=': 'iexact', 不精确匹配,相当于数据库中的like
    - 哪些情况下,不会进行过滤?
            1.如果全局未指定过滤引擎
            2.如果search_fields类属性为空
            3.如果前端在搜索时,未指定search查询字符串参数
    """
    search_fields = ['^name', '=tester']

    """
    排序:
    - ordering_fields 指定模型类中支持排序的字段名称
    - ordering_fields = '__all__' 代表所有字段都可进行排序
    - 在前端需要使用ordering作为排序的查询字符串参数名称
    - 前端可以在字段前添加“-”,进行逆序排序,默认为升序
    - 在前端可以指定多个排序字段,每个排序字段之间使用逗号分隔,如:?ordering=-id,name
    - ordering指定使用默认排序字段,如:ordering = ['name']
    """
    ordering_fields = ['id', 'name', 'tester']
    
    """在类视图中指定分页引擎,优先级高于全局"""
    pagination_class = PageNumberPagination

 

3、对于分页引擎PageNumberPagination,重写PageNumberPagination,可以修改参数名称,页码等

from rest_framework.pagination import PageNumberPagination as _PageNumberPagination


"""
重写PageNumberPagination,可以修改参数名称,页码等
"""
class PageNumberPagination(_PageNumberPagination):
    # 指定默认每一页显示的数据条数
    page_size = 3
    # 前端用于指定页号的查询字符串参数名称(默认page)
    page_query_param = 'page'
    # 指定前端用于指定页号的查询字符串参数的描述
    page_query_description = '获取的页码'
    page_size_query_param = "page_size"
    # 前端用于指定每一页的数据条数,查询字符串参数名称
    # 只要设置了page_size_query_param,那么前端就支持指定获取每一页的数据条数
    # 前端用于指定每一页的数据条数,查询字符串参数的描述
    page_size_query_description = '每一页数据条数'
    max_page_size = 100

    def get_paginated_response(self, data):
        """
        重写get_paginated_response,返回参数新增当前页码
        """
        response = super().get_paginated_response(data)
        response.data['current_num'] = self.page.number
        return response

 

4、请求方法中增加过滤方法

    def get(self, request: Request):
        """获取list列表信息"""

        """
        查询(搜索、排序):
            a.必须调用self.filter_queryset方法,进行过滤
            b.需要传递查询集对象作为参数
        """
        queryset = self.filter_queryset(self.get_queryset())  # self.get_queryset()方法获取queryset

        """
        分页:
            a.使用paginate_queryset方法,进行分页操作
            b.需要接收查询集参数
            c.如果返回的数据为空,说明不进行分页操作,否则需要进行分页操作
            d.必须调用get_paginated_response方法返回
        """
        page = self.paginate_queryset(queryset)

        if page is not None:
            serializer = self.get_serializer(instance=page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(instance=queryset, many=True)

        # a.第一个参数为Python中的常用数据类(字典或者嵌套字典的列表),serializer.data
        # b.status参数用于传递响应状态码
        # c.Response对象.data属性,可以获取返回给前端的数据
        return Response(serializer.data, status=status.HTTP_200_OK)

 

posted @ 2021-03-04 12:39  mkay  阅读(342)  评论(0编辑  收藏  举报