七、Django DRF框架GenericAPIView--搜索&排序&分页&返回值

这篇具有很好参考价值的文章主要介绍了七、Django DRF框架GenericAPIView--搜索&排序&分页&返回值。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上一章:

六、DRF框架APIView--request&response解析器&渲染器_做测试的喵酱的博客-CSDN博客

下一章:

一、GenericAPIView介绍

APIView 继承 View

GenericAPIView 继承 APIView。

GenericAPIView 功能:

  •     a.具备View的所有特性
  •     b.具备了APIView中的认证、授权、限流功能
  •     c.还支持对于获取列表数据接口的功能:搜索、排序、分页

GenericAPIView的引用:

from rest_framework.generics import GenericAPIView

二、GenericAPIView的使用

1、视图类,需要继承GenericAPIView

2、需要定义类属性, queryset 查询集、  serializer_class 指定当前类视图的实例方法需要使用的序列化器类

3、在函数中,

  1. 调用queryset 查询集 方法:self.get_queryset()
  2. 调用查询集中单个实例对象    project_obj = self.get_object()
  3. 调用序列化器实例 方法: serializer = self.get_serializer(instance=project_obj)
class ProjectsView(GenericAPIView):
    """
    继承GenericAPIView父类(GenericAPIView子类)
    a.具备View的所有特性
    b.具备了APIView中的认证、授权、限流功能
    c.还支持对于获取列表数据接口的功能:搜索、排序、分页
    """
    # 一旦继承GenericAPIView之后,往往需要指定queryset、serializer_class类属性
    # queryset指定当前类视图的实例方法需要使用的查询集对象
    queryset = Projects.objects.all()
    # serializer_class指定当前类视图的实例方法需要使用的序列化器类
    serializer_class = ProjectSerilizer

三、GenericAPIView实现搜索

GenericAPIView实现搜索

3.1、在Django的setting文件中 设置搜索引擎

在Django的setting文件中,REST_FRAMEWORK 下,在全局DEFAULT_FILTER_BACKENDS指定使用的过滤引擎类(SearchFilter为搜索引擎类)

REST_FRAMEWORK = {
 

    # 1、在全局DEFAULT_FILTER_BACKENDS指定使用的过滤引擎类(SearchFilter为搜索引擎类)
    'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.SearchFilter',
                                'rest_framework.filters.OrderingFilter'],
    # 可以在全局使用SEARCH_PARAM修改前端过滤查询字符串参数名称(默认为search)
    # 'SEARCH_PARAM': 'se',

    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 3,
}

3.2、视图类引用搜索引擎

1、视图类属性,设置需要搜索的字段

search_fields = ['id', 'name', 'leader']

搜索类型, 使用icontains查询类型作为过滤类型。(忽略大小写)

指定查询类型:

  可以在字段名称前添加相应符号,指定查询类型

  •   '^': 'istartswith', 以xx开头
  •    '=': 'iexact',完全命中
  •   '$': 'iregex',正则

默认,是icontains查询类。忽略大小写的包含 search_fields = ['id', 'name', 'leader']

^以什么开头,如以name开头的数据

=完全命中,如leader字段

search_fields = ['^name', '=leader', 'id']

2、获取经过过滤的查询集结果

        # filter_queryset对查询对象进行过滤操作
        queryset = self.filter_queryset(self.get_queryset())

3、搜索演示

http://127.0.0.1:8000/projects/?search=x项目

注意:

  • 1、搜索时,搜索关键字默认为search
  • 2、搜索的值,不需要加引号,如search=‘x项目’ 是错误的。

4、修改搜索关键词

默认搜索关键词,是search

想要自定义搜索关键词,在setting文件中,通过 'SEARCH_PARAM' 实现:

REST_FRAMEWORK = {
 

    # 1、在全局DEFAULT_FILTER_BACKENDS指定使用的过滤引擎类(SearchFilter为搜索引擎类)
    'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.SearchFilter',
                                'rest_framework.filters.OrderingFilter'],
    # 可以在全局使用SEARCH_PARAM修改前端过滤查询字符串参数名称(默认为search)
    'SEARCH_PARAM': 'mysearch',

    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 3,
}

 http://127.0.0.1:8000/projects/?mysearch=x项目

3.3、视图类中定义搜索引擎

1、背景:

在setting中,定义的是项目全局的搜索引擎。

如果我想,只在某几个视图类中,使用搜索引擎,则需要在对应的视图类中,设置搜索引擎。

2、视图类中 设置引擎。

优先级高于全局设置的引擎。


    from rest_framework import filters


    class ProjectsView(GenericAPIView):

    # filter_backends在继承了GenericAPIView的类视图中指定使用的过滤引擎类(搜索、排序)
    # 优先级高于全局
    filter_backends = [filters.SearchFilter]

四、GenericAPIView实现(搜索结果的)排序功能

想要对搜索结果进行排序,需要使用排序引擎OrderingFilter

4.1 设置排序引擎OrderingFilter

设置排序,引擎,有两种方式,1、在setting中设置全局引擎,对整个项目适用

2、在视图类中设置局部引擎,对当前的视图类生效。

4.1.1 在setting中设置全局引擎

注意,这里使用的是字符串

REST_FRAMEWORK = {
  
    # 1、在全局DEFAULT_FILTER_BACKENDS指定使用的过滤引擎类(SearchFilter为搜索引擎类)
    'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.SearchFilter',
                                'rest_framework.filters.OrderingFilter'],

4.1.2 在视图类中设置局部引擎

from rest_framework import filters
class ProjectsView(GenericAPIView):

    # 一旦继承GenericAPIView之后,往往需要指定queryset、serializer_class类属性
    # queryset指定当前类视图的实例方法需要使用的查询集对象
    queryset = Projects.objects.all()
    # serializer_class指定当前类视图的实例方法需要使用的序列化器类
    serializer_class = ProjectSerilizer

    # filter_backends在继承了GenericAPIView的类视图中指定使用的过滤引擎类(搜索、排序)
    # 优先级高于全局
    filter_backends = [filters.SearchFilter, filters.OrderingFilter]

4.2视图类中,设置排序字段 

想要支持哪些字段的排序,需要在视图类中,定义 ordering_fields 。

如下,设置支持id 、name、leader的排序

    # ordering_fields类属性指定模型类中允许前端进行排序的字段名称
    # 前端默认可以使用ordering作为排序功能查询字符串参数名称,默认改字段的升序
    # 如果在字段名称前添加“-”,代表改字段降序
    # 如果指定多个排序字段,使用英文逗号进行分割
    ordering_fields = ['id', 'name', 'leader']

4.3 查询结果 

  # filter_queryset对查询对象进行过滤操作
  queryset = self.filter_queryset(self.get_queryset())

4.4 查询演示 ,查询排序关键字ordering

1、默认升序

查询name为张三,并且将查询结果按照name排序

http://127.0.0.1:8000/projects/?search=张三&ordering=name

2、降序排序,在字段名前加上-

如按照name降序排序,-name

http://127.0.0.1:8000/projects/?search=张三&ordering=-name

3、按照多个字段排序

多个字段排序,使用逗号隔开。

按照name与leader排序,name降序,leader升序

http://127.0.0.1:8000/projects/?search=张三&ordering=-name,leader

五、分页引擎 PageNumberPagination

5.1 设置分页引擎PageNumberPagination

5.1.1 在setting中,设置全局分页引擎PageNumberPagination

REST_FRAMEWORK = {

    # 1、在全局DEFAULT_FILTER_BACKENDS指定使用的过滤引擎类(SearchFilter为搜索引擎类)
    'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.SearchFilter',
                                'rest_framework.filters.OrderingFilter'],
    # 可以在全局使用SEARCH_PARAM修改前端过滤查询字符串参数名称(默认为search)
    # 'SEARCH_PARAM': 'se',

    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 8,
}

分页引擎:

 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',

一页个数:
   'PAGE_SIZE': 10,

5.1.2 在视图类中,设置局部分页引擎PageNumberPagination

1、在视图类的py文件中,引入PageNumberPagination

from rest_framework.pagination import PageNumberPagination

2、 在视图类的属性汇总,指定分页引擎

   # 可以在类视图中指定分页引擎类,优先级高于全局
    pagination_class = PageNumberPagination


 

5.2 视图类中设置分页

   def get(self, request: Request):
    

        # filter_queryset对查询对象进行过滤操作
        queryset = self.filter_queryset(self.get_queryset())
       
        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)
        return Response(serializer.data, status=status.HTTP_200_OK)

1、先判断,(请求)是否需要进行分页处理

page = self.paginate_queryset(queryset)

没有做分页处理时,page的值为None。

做了分页处理,page的值为分页后的查询集

2、对分页的数据进行处理

        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)

3、没有做分页处理时(page为none时),返回正常的查询集结果。

六、自定义分页功能(支持用户指定一页数据的个数)

在五中,用户请求,只能指定页码,但是不能指定一页多少条数据。

我们通过重写PageNumberPagination类实现。

6.1 重写PageNumberPagination类

在utils文件夹下,新建文件pagination.py。通过继承的方式,重写PageNumberPagination类。

pagination.py

from rest_framework.pagination import PageNumberPagination as _PageNumberPagination


class PageNumberPagination(_PageNumberPagination):
    # 指定默认每一页显示5条数据
    page_size = 5

    # 前端用于指定页码的查询字符串参数名称
    page_query_param = 'page'
    # 前端用于指定页码的查询字符串参数描述
    page_query_description = '获取的页码'

    # 前端用于指定每一页显示的数据条数,查询字符串参数名称
    page_size_query_param = 'page_size'
    page_size_query_description = '每一页数据条数'

    max_page_size = 50
    invalid_page_message = '无效页码'

1、通过继承的方式,重写PageNumberPagination

2、我们自定义的类,名称也想叫做 PageNumberPagination 。解决办法:先引入父类PageNumberPagination,然后再给他取一个别名。

from rest_framework.pagination import PageNumberPagination as _PageNumberPagination


class PageNumberPagination(_PageNumberPagination):

3、设置一页数据个数

    # 指定默认每一页显示5条数据
    page_size = 5

4、设置页码关键字

# 前端用于指定页码的查询字符串参数名称
page_query_param = 'page'

‘page’是自定义的,可以换成其他字符串 

5、设置指定一页数据个数关键字

    # 前端用于指定每一页显示的数据条数,查询字符串参数名称
    page_size_query_param = 'page_size'
    page_size_query_description = '每一页数据条数'

‘page_size’是自定义的,可以换成其他字符串 

6、指定一页多少数据的最大限制

max_page_size = 50
invalid_page_message = '无效页码'

 6.2 在视图类中使用自定义的PageNumberPagination类

1、先在py文件中,引入 自定义的PageNumberPagination类

from utils.pagination import PageNumberPagination

2、在视图类中,设置 PageNumberPagination类

    # 可以在类视图中指定分页引擎类,优先级高于全局
    pagination_class = PageNumberPagination

视图类的整体代码如下:

class ProjectsView(generics.ListCreateAPIView):

    queryset = Projects.objects.all()
    serializer_class = ProjectModelSerializer

    filter_backends = [filters.SearchFilter, filters.OrderingFilter]
    search_fields = ['=name', '=leader', '=id']
    ordering_fields = ['id', 'name', 'leader']

    # 可以在类视图中指定分页引擎类,优先级高于全局
    pagination_class = PageNumberPagination

 6.3 请求演示

请求第2页数据,设置一页6条数据

http://127.0.0.1:8000/projects/?page=2&page_size=6

七、其他筛选过滤方式

官网:

Filtering - Django REST framework中文站点

DjangoFilterBackend(Django过滤后端)

django-filter库包含一个为REST framework提供高度可定制字段过滤的DjangoFilterBackend类。

要使用DjangoFilterBackend,首先要先安装django-filter

pip install django-filter

现在,你需要将filter backend 添加到你django project的settings中:

    REST_FRAMEWORK = {
        'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
    }

或者你也可以将filter backend添加到一个单独的view或viewSet中:

    from django_filters.rest_framework import DjangoFilterBackend

    class UserListView(generics.ListAPIView):
        ...
        filter_backends = [DjangoFilterBackend]

如果只需要简单的根据是否相等的过滤,则可以在视图或视图集上设置filterset_fields属性,列出要过滤的字段集合。

class ProductList(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['category', 'in_stock']

这将自动为给定的字段创建一个FilterSet类,并允许你发出如下请求:

http://example.com/api/products?category=clothing&in_stock=True

对于更高级的过滤要求,你可以指定视图应使用的FilterSet类。你可以在django-filter文档中阅读有关FilterSets的更多信息。还建议你阅读有关DRF集成的部分。

八、重写返回值

GenericAPIView 的返回值,使用的是 return self.get_paginated_response(serializer.data)。

返回结果,包含字段为

   {
        "count":xxx,
        "next":xxxx,
        "previous":xxx,
        "reslut": 数据值
    }

count为数据总数

next 为下一页地址

previous 是上一页地址

如果这些字段不满足我们的需求,我们需要在返回结果中,添加当前页面的页码、最大的页码,通过重写 PageNumberPagination类的 get_paginated_response 方法实现。

from rest_framework.pagination import PageNumberPagination as _PageNumberPagination


class PageNumberPagination(_PageNumberPagination):
    # 指定默认每一页显示5条数据
    page_size = 5

    # 前端用于指定页码的查询字符串参数名称
    page_query_param = 'page'
    # 前端用于指定页码的查询字符串参数描述
    page_query_description = '获取的页码'

    # 前端用于指定每一页显示的数据条数,查询字符串参数名称
    page_size_query_param = 'page_size'
    page_size_query_description = '每一页数据条数'

    max_page_size = 50
    invalid_page_message = '无效页码'

    def get_paginated_response(self, data):
        response = super().get_paginated_response(data)
        response.data['current_num'] = self.page.number
        response.data['max_num'] = self.page.paginator.num_pages
        return response

再使用PageNumberPagination 的视图模块中,引入自定义的类,而不是框架自带的PageNumberPagination类。文章来源地址https://www.toymoban.com/news/detail-474230.html

到了这里,关于七、Django DRF框架GenericAPIView--搜索&排序&分页&返回值的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 43--Django-项目实战-全栈开发-基于django+drf+vue+elementUI企业级项目开发流程-课程详情页面、搜索页面以及后台设计

    1.视频播放功能 下载第三方插件:vue-video-player 使用步骤: 第一步: cnpm install vue-video-player 第二步:在main.js中引入

    2024年02月09日
    浏览(39)
  • Elasticsearch(八)搜索---搜索辅助功能(上)--指定搜索返回字段,结果计数和分页

    前面我们已经将ES的基础操作(索引,映射,文档)学习过了,从这一章开始,我们便开始学习ES的最大的功能—搜索 ES为用户提供了丰富的搜索功能:既有基本的搜索功能,又有搜索建议功能;既有常用的普通类型的匹配功能,又有基于地理位置的搜索功能;既提供了分页搜

    2024年02月05日
    浏览(39)
  • 【Django】列表数据Paginatior分页,动态返回页码,显示当前页、总页数、跳转页

    1、当返回数据较多,如设置每页展示10条,数据接近200条,返回页码范围1~20,前端每个页码都显示的话,就会出现页码超出当前页面,被遮挡的页码无法操作和显示不美观; 2、列表的所在页码,总分页数,跳转不在动态页面的页数 在使用paginator转化为Page对象后,获取到n

    2024年02月12日
    浏览(31)
  • 【Django学习】(十一)APIView_请求与响应_GenericAPIView

      继承DRF中APIView之后,那么当前视图就具备了认证、授权、限流等功能  继承DRF中APIView之后,每一个实例方法中的request为Request对象  Request类拓展了Django中的HttpRequest类,具备很多额外优秀的功能 Request类与HttpRequest类中的所有功能兼容 查询字符串参数: request.GET、request.q

    2024年02月13日
    浏览(37)
  • Elasticsearch:RestHighLevelClient实现搜索、分页、排序、高亮

    1.引入依赖 2.自定义搜索DTO 3.封装工具类、实现 分页、高亮、排序 反射工具类 ReflectUtil 是我自定义的,原理是反射,可以引入hutool的工具包,同样也可以实现该结果

    2024年02月11日
    浏览(33)
  • Elasticsearch (ES) 搜索引擎: 搜索功能:搜索分页、搜索匹配、全文搜索、搜索建议、字段排序

    原文链接:https://xiets.blog.csdn.net/article/details/132348920 版权声明:原创文章禁止转载 专栏目录:Elasticsearch 专栏(总目录) ES 搜索 API 官网文档:Search APIs 先创建一个索引,并写入一些文档用于搜索示例: 写入一些文档示例: 官网API:The _source option 搜索结果中的文档数据封装

    2024年02月08日
    浏览(45)
  • 微服务分布式搜索引擎 ElasticSearch 搜索结果处理 排序、分页与高亮

    本文参考黑马 分布式Elastic search Elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容 搜索结果处理 搜索的结果可以按照用户指定的方式去处理或展示。 elasticsearch默认是根据相关度算分(_score)来排序,但是也支

    2024年02月02日
    浏览(48)
  • Django搜索排序

    Django提供了一个SearchQuery类把查询词转换为一个搜索查询对象。 使用全文搜索的实例,根据查询词出现的频率和它们之间的距离对结果进行排序。 关于全文搜索更多内容,请看Django全文搜索-CSDN博客 编辑views.py,添加以下导入 找到post_search 替换为 创建一个SearchQuery对象,通过

    2024年01月21日
    浏览(57)
  • DRF 分页器的使用

    drf提供了三个内置分页器,根据前端需求选择使用。 在配置文件中设置全局的分页方式,如: 也可通过继承内置的分页器类自定义Pagination类,来为视图添加不同分页器。在视图中通过 pagination_clas 属性来指明。 注意 :视图内局部设置不使用分页器 内置分页器的使用有两种

    2024年02月03日
    浏览(30)
  • DRF03-权限与分页

    创建一个新的子应用 opt 注册子应用 总路由,代码: 子路由,代码: 因为接下来的认证组件中需要使用到登陆功能,所以我们使用django内置admin站点并创建一个管理员. admin运营站点的访问地址:http://127.0.0.1:8000/admin 创建管理员以后,访问admin站点,先修改站点的语言配置

    2024年02月09日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包