【Django学习】(十二)GenericAPIView_过滤_排序_分页

上篇文章初步接触了GenericAPIView,这次来更加深入的学习它,了解里面的一些使用和方法

  • get_object:源码中:处理查询集,并含有所需要得pk值,lookup_field
  • get_queryset:源码中:先判断queryset是否为空,不为空得话就会替代queryset,所以事先要先声明,
    • 后面可以轻松重写的queryset,实现不同接口使用不同查询集
  • get_serializer:源码中:先判断serializer_class是否为空,不为空就返回serializer_class
    return  serializer_class(*args, **kwargs);
    • 后面我们可以根据不同接口,重写get_serializer_class这个方法,实现不同接口返回不一样的字段
  • 继承关系:generic.genericAPIView继承View.APIView(如图)

 

 补充说明

1、queryset

一般使用类属性的queryset只会查一次,因为queryset是惰性查询;

1、如果还是使用queryset的话,在调用一次queryset后,后面再调用时候就不会改变,

2、这里的queryset不太容易重写,因为每个接口使用的数据源是不一样的,不一定都使用某一个模型类的查询集,不会使用一模一样的数据

2、serializer_class 

一般不会使用serializer_class来获取序列化器类

1、因为每个接口需要返回的字段不一定都是相同的,无法实现定制化

3、(路由表中的主键名称pk):

1、如果定义路由表时,指定的主键名称为pk,那么无需指定lookup_field;

2、如果不想请求数据里的主键名称为pk,比如想叫做id之类的,可以在对应的视图类里重写 lookup_field属性

lookup_field = 'Id'

同时应用里的路由表里的路径参数也要保持一致,修改urlpatterns配置:

path('projects/<int:Id>/',views.ProjectsDetailViews.as_view())

 一、过滤

方式一:手写过滤逻辑代码实现功能

    # 查询全部数据
    def get(self, request):
        qs = self.get_queryset()
        param=request.query_params.get('name')
        qs=qs.filter(name__icontains=param)
        serializer_obj = self.get_serializer(instance=qs, many=True)
        return Response(serializer_obj.data, status=status.HTTP_200_OK)

 param=request.query_params.get('name')为获取查询字符串参数的值,例如下面请求里的name=1

 方式二:使用的是rest_framework中的filters.py中SearchFilter查询类

1、全局使用过滤引擎

1.1 可以在全局配置文件setting.py中,指定默认的过滤引擎,引用rest_framework的过滤引擎(所有获取列表数据的接口都会支持过滤功能)

'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.SearchFilter'],

1.2 在对应的视图类里 定义需要过滤的字段

search_fields=['name','id']
1、'^': 'istartswith',name以什么开头进行过滤(search_fields=['^name','id'])
2、'=': 'iexact',以name等于什么,进行精确匹配过滤(search_fields=['=name','id'])
3、'@': 'search',不常用
4、'$': 'iregex',name字段支持正则匹配(search_fields=['$name','id'])
5、如果不写前缀,默认使用icontains进行匹配过滤

 默认情况下,过滤字段是search,如果需要自定义过滤字段,可以在setting.py配置文件中重写SEARCH_PARAM属性

'SEARCH_PARAM': 'Search',

 

2、局部使用过滤引擎

如果不想全局引用过滤引擎,只想给指定的列表接口添加过滤引擎,那就不需要再setting.py中引用过滤引擎,可以在特定的类视图中指定filter_backends过滤引擎,也可以指定排序引擎

 1、可以使用GenericAPIView内置的filter_queryset方法 ,对查询集进行过滤,省略自己的的代码,达到简化代码的目的

2、filter_queryset的第一个参数是查询集对象

3、注意:视图类里声明的引擎列表里过滤引擎和排序引擎不是字符串参数

二、排序

方式一:自定义代码逻辑进行排序

    # 查询全部数据
    def get(self, request):
        qs = self.get_queryset()
        #param=request.query_params.get('name')
        qs=qs.filter().order_by('-name')
        serializer_obj = self.get_serializer(instance=qs, many=True)
        return Response(serializer_obj.data, status=status.HTTP_200_OK)

 方式二:使用的是rest_framework中的filters.py中OrderingFilter查询类

1、全局配置排序引擎

1.1 可以在全局配置文件setting.py中,指定默认的排序引擎,引用rest_framework的过滤引擎(所有获取列表数据的接口都会支持排序功能)
    'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.SearchFilter'],
    'ORDERING_PARAM': 'ordering',
 1.2 在视图类里定义需要排序的字段
# 定义需要排序的字段
ordering_fields=['id','name']

2、局部使用排序引擎

class ProjectsViews(GenericAPIView):
    # 指定当前类视图需要使用的查询集
    queryset = ProjectsModel.objects.all()
    # 指定当前类视图需要使用的序列化器类
    serializer_class = ProjectModelSerializer
    # lookup_field = 'Id'
    # 声明需要使用的引擎类
    filter_backends = [filters.SearchFilter,filters.OrderingFilter]
    # 定义需要过滤的字段
    search_fields=['name','id']
    # 定义需要排序的字段
    ordering_fields=['id','name']

  1. 如果不想全局引用排序引擎,只想给指定的列表接口添加排序引擎,那就不需要再setting.py中引用排序引擎,可以在特定的类视图中指定filter_backends排序引擎
  2. 视图类中添加排序引擎 filter_backends =[filters.OrderingFilter]
  3. 定义需要排序的字段 ordering_fields=['id','name']

 api的可浏览界面中会添加排序功能

 

 

默认情况下,排序字段是ordering,如果需要自定义过滤字段,可以在setting.py配置文件中重写ORDERING_PARAM属性

​​​​​​​'ORDERING_PARAM': 'ordering',

三、分页

1、使用rest_framework中的分页引擎

全局配置文件中指定分页引擎DEFAULT_PAGINATION_CLASS,并且指定每页数据数量参数PAGE_SIZE;

'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 3,
    # 查询全部数据
    def get(self, request):
        qs = self.get_queryset()
        qs=self.filter_queryset(qs)
        #需要调用paginate_queryset方法,需要传递序列化之后的字典或者嵌套字典的列表
        page_queryset=self.paginate_queryset(qs)
        #如果定义了分页引擎,则使用get_paginated_response进行返回,否则默认返回不分页的全部数据
        if page_queryset is not None:
            serializer_obj = self.get_serializer(instance=page_queryset, many=True)
            return self.get_paginated_response(serializer_obj.data)
        serializer_obj = self.get_serializer(instance=page_queryset, many=True)
        return Response(serializer_obj.data, status=status.HTTP_200_OK)
  •  调用paginate_queryset方法,需要传递查询集对象
  • 需要调用get_paginated_response方法,需要传递序列化之后的字典或者嵌套字典的列表
  • 如果定义了分页引擎,则使用get_paginated_response进行返回,否则默认返回不分页的全部数
  • get_paginated_response返回Response对象,在返回的数据中,添加了特定的数据
    • count :数据的总数量
    • next :下一页的链接link
    • previous :上一页的链接link
    • results :查询结果data

 2、自定义分页引擎类

2.1 自定义一个分页引擎类

from rest_framework.pagination import PageNumberPagination as _PageNumberPagination

class PageNumberPagination(_PageNumberPagination):
    # 分页关键字,来查看对应页的数据
    page_query_param='p'
    # 每页指定展示多少条数据
    page_size_query_param='s'
    # 设置每页数据量虽大值
    max_page_size=20
    # 无效页面提示信息
    invalid_page_message='这是个无效页面,请检查后重新输入....'

2.2 然后再全局配置文件setting.py里替换掉自己定义的分页类

    'DEFAULT_PAGINATION_CLASS':'utils.pagination.PageNumberPagination',
    'PAGE_SIZE': 3,

 接下来url里拼接上p=2&s=1,表示展示第二页,每页展示1条数据

 当输入的页数不存在时,就会抛出自定义的无效分页的描述

3、给指定的类视图定制一个分页引擎

就需要在指定的类视图中引用我们自定义的分页引擎

3.1 导入自定义分页引擎类

from utils.pagination import PageNumberPagination

3.2 声明需要使用的分页引擎

pagination_class = PageNumberPagination

如果我们还是按照全局分页引擎来分页,是无效的

 如果我们按照自定义的分页引擎来分页,是有效的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/36595.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

可使用Linux 测试IP和端口是否能访问,查看返回状态码

一、 使用wget判断 wget是linux下的下载工具&#xff0c;需要先安装. 用法: wget ip:port wget ip:port连接存在的端口 二、使用telnet判断 telnet是windows标准服务&#xff0c;可以直接用&#xff1b;如果是linux机器&#xff0c;需要安装telnet. 用法: telnet ip port…

uniapp电子签名以及竖屏签名后内容旋转90度变为横屏图片

用该插件挺不错的 电子签名插件地址 如果你一个页面要用多个该插件&#xff0c;就改成不同的cavas-id&#xff0c;修改插件源码 效果图 竖屏写 旋转成横屏图片 插件内 在拿到签名临时地址后的页面 <!-- 旋转图片canvas --> <canvas canvas-id"camCacnvs&quo…

MySQL-SQL存储函数以及触发器详解

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a; 小刘主页 ♥️努力不一定有回报&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️学习两年总结出的运维经验&#xff0c;以及思科模拟器全套网络实验教程。专栏&#xf…

15 Java 使用for进行死循环

括号里直接写两个分号即可。for(;;) package demo;public class Demo8 {public static void main(String[] args) {for (;;){System.out.println("你是最棒的&#xff01;");}} }

springboot高校党务系统

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9

神经网络解决预测问题(以共享单车预测为例)

背景:大约从2015年起,共享单车席卷了大部分城市。共享单车在给人们带来便利的同时,也存在一些问题:单车的分布很不均匀。比如在早高峰的时候,一些地铁口往往聚集着大量的单车,而到了晚高峰却很难找到一辆单车了。那么如何解决共享单车分布不均匀的问题呢?目前,共享单车…

Docker镜像

是什么 是一种轻量级、可执行的独立软件包&#xff0c;它包含运行某个软件所需的所有内容&#xff0c;我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等)&#xff0c;这个打包好的运行环境就是image镜像文件。 只有通…

离散化模板(附 区间和 解决方法)

目录 用于解决的问题类型&#xff1a; 作用&#xff1a; 使用到的函数&#xff1a; 常用模板&#xff1a; 例题引入&#xff1a; 题目&#xff1a; 解题思路&#xff1a; 代码详解&#xff1a; 用于解决的问题类型&#xff1a; 对于值域比较大&#xff0c;但个数比较少…

Window10 系统 RabbitMQ的安装和简单使用

1、下载 & 安装 Erlang 因为RabbitMQ的服务端是基于 Erlang编写的&#xff0c;所以&#xff0c;首先需要安装Erlang。 1&#xff09;下载 下载地址如下&#xff1a; https://www.erlang.org/downloads此处下载比较慢&#xff0c;可以参考如下百度网盘&#xff1a; 链接…

SSM框架训练 实现各个功能时遇到的常见问题

快速复制当前代码到下一行&#xff1a;ctrlD 格式化代码&#xff08;快速整理代码&#xff09;&#xff1a;ctrilaltL 一步一步来&#xff0c;后续会不停添加功能。 先创建项目结构&#xff1a;搭建框架 (36条消息) SSM框架模板&#xff08;高配&#xff1a;一次性配完所有…

vue 多环境打包指令配置及编译

1.创建多环境: 在根目录创建.env.xxx文件,如下为例(我创建了两个) 文件内容主要包括&#xff1a; # 页面标题 VUE_APP_TITLE "标题"# 生产环境配置 ENV production# DNA检测仓储管理系统/生产环境 VUE_APP_BASE_API https://xxxxxx 2.设置: 修改根目录下的package…

freemark生成pdf

freemark生成pdf 字体库 simsun.ttc 解决中文问题 /*** 生成pdf* param params* param templPath* param ftlName* param htmlPath* param pdfPath* param fontPath* return*/public String processPdf(Map<String, Object> params, String templPath, String ftlName,…

SSM+Shiro安全框架整合(完成安全认证--登录+权限授权)+ssm整合shiro前后端分离

目录 1.搭建SSM框架 1.1.引入相关的依赖 1.2. spring配置文件 1.3. web.xml配置文件 1.4.配置Tomcat并启动 2.ssm整合shiro---认证功能 (1).引入依赖 (2).修改spring配置文件 (3).修改web.xml文件 (4).新建login.jsp(登录页面) (5).新建success.jsp(登录成功后跳转到此…

监听DOM尺寸变化 - ResizeObserver

一、与 MutationObserver Api的区别 MutationObserver 主要用来监听 DOM 元素的属性和节点变化的&#xff0c;非 DOM 样式尺寸&#xff0c;可查看之前一篇 blog - DOM规范 - MutationObserver接口观察DOM元素的属性和节点变化ResizeObserver 主要用来监听 DOM 元素的 内容区域…

系统运维和网络运维有什么区别吗?

跟着互联网以及科技的高速开展&#xff0c;衍生出了许多的新奇职业&#xff0c;比方网络运维、网络安全运维。 从字面意思了解&#xff0c;两者之间没有什么太大区别&#xff0c;因而很多人很容易将两者混杂。 系统和网络运维有什么区别? 一个偏系统&#xff08;linux、doc…

23款奔驰GLS450更换迈巴赫GLS600外观套件,尽显奢华

在外观上不要过分的张扬&#xff0c;低调的同时还要彰显强大的气场&#xff0c;换装迈巴赫专属套件&#xff0c;迈巴赫专属踏板&#xff0c;还有迈巴赫的醒目M标志&#xff0c;车身轮廓和线条方面&#xff0c;奔驰GLS450和迈巴赫GLS600尺寸及其契合&#xff0c;只需通过增加一些…

网络安全(黑客)学习路线

前言&#xff1a; 学基础花费很长时间&#xff0c;光语言都有几门&#xff0c;有些人会倒在学习 linux 系统及命令的路上&#xff0c;更多的人会倒在学习语言上&#xff1b;1、打基础时间太长 对于网络安全基础内容&#xff0c;很多人不清楚需要学到什么程度&#xff0c;囫囵…

Spark-用IDEA编写wordcount demo

配置 Spark版本&#xff1a;3.2.0 Scala版本&#xff1a;2.12.12 JDK&#xff1a;1.8 Maven&#xff1a;3.6.3 pom文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi&quo…

【Redis】—— Redis的AOF持久化机制

&#x1f4a7; 【 R e d i s 】—— R e d i s 的 A O F 持久化机制 \color{#FF1493}{【Redis】 —— Redis的AOF持久化机制} 【Redis】——Redis的AOF持久化机制&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞…

基于单片机语音识别智能家居系统的设计与实现

功能介绍 以STM32单片机作为主控系统&#xff1b;液晶显示当前环境温湿度&#xff0c;用电器开关状态通过语音模块识别设定的语音&#xff1b;DHT11进行环境温湿度采集&#xff1b;通过语音播报模块报当前温湿度&#xff0c;智能回复通过语音识别可以打开灯&#xff0c;窗帘&am…