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

news2024/11/27 21:38:48

上篇文章初步接触了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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全志F1C200S嵌入式驱动开发(linux移植)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 前面完成了uboot移植,下面就要进行linux移植。当然,理论上uboot只是为后续的os准备好了一个基础运行环境,实际运行的操作系统是不是选择linux,也不一定。如果为了实际生产的需要…

Golang环境搭建指南(Windows和linux)

前言&#xff1a; go语言和Java&#xff0c;Python&#xff0c;C语言等等基本一样&#xff0c;也是需要在系统内集成语言环境的。语言基本都一样&#xff0c;支持各种系统架构&#xff0c;比如&#xff0c;mac&#xff0c;Windows&#xff0c;linux系统支持。本文仅以最为常用…

Django_Paginator分页器

目录 分页器代码说明 简单demo 源码等资料获取方法 分页器代码说明 import os import random # 需要导入分页器类from django.core.paginator import Paginator, EmptyPage# 导入配置django配置文件 os.environ.setdefault(DJANGO_SETTINGS_MODULE, dailyfresh.settings)it…

Java的Hibernate框架中集合类数据结构的映射编写教程

Java的Hibernate框架中集合类数据结构的映射编写教程 一、集合映射 1.集合小介 集合映射也是基本的映射&#xff0c;但在开发过程中不会经常用到&#xff0c;所以不需要深刻了解&#xff0c;只需要理解基本的使用方法即可&#xff0c;等在开发过程中遇到了这种问题时能够查询…

《机器学习公式推导与代码实现》chapter5-线性判别分析LDA

《机器学习公式推导与代码实现》学习笔记&#xff0c;记录一下自己的学习过程&#xff0c;详细的内容请大家购买作者的书籍查阅。 线性判别分析 线性判别分析(linear discriminant analysis, LDA)是一种经典的线性分类方法&#xff0c;其基本思想是将数据投影到低维空间&…

openGauss学习笔记-06 openGauss 基本概念

文章目录 openGauss学习笔记-06 openGauss 基本概念6.1 数据库&#xff08;Database&#xff09;6.2 数据块&#xff08;Block&#xff09;6.3 行&#xff08;Row&#xff09;6.4 列&#xff08;Cloumn&#xff09;6.5 表&#xff08;Table&#xff09;6.6 数据文件&#xff08…

Opencv之角点 Harris、Shi-Tomasi 检测详解

角点&#xff0c;即图像中某些属性较为突出的像素点 常用的角点有以下几种&#xff1a; 梯度最大值对应的像素点两条直线或者曲线的交点一阶梯度的导数最大值和梯度方向变化率最大的像素点一阶导数值最大&#xff0c;但是二阶导数值为0的像素点 API简介&#xff1a; void c…

Go语言网络编程:HTTP服务端之底层原理与源码分析——http.HandleFunc()、http.ListenAndServe()

一、启动 http 服务 import ("net/http" ) func main() {http.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {w.Write([]byte("ping...ping..."))})http.ListenAndServe(":8999", nil) }在 Golang只需要几行代…

MySQL存储过程和存储函数练习

创建表并插入数据 字段名 数据类型 主键 外键 非空 唯一 自增 id INT 是 否 是 是 否 name VARCHAR(50) 否 否 是 否 否 glass VARCHAR(50) 否 否 是 否 否 sch 表内容 id name glass 1 xiaommg glass 1 2 xiaojun glass 2 1、创建一个可以统计表格内记录条数的存储函数 &#…

耳夹式骨传导耳机哪个牌子好?耳夹骨传导耳机推荐

骨传导耳机品牌越来越多&#xff0c;选择骨传导耳机时可不是一件简单的事&#xff0c;在挑选的时候首先需要考虑到耳机自身的综合性能&#xff0c;以及耳机的配置如何都会影响到我们使用耳机的幸福感&#xff0c;接下来我来给大家挑选几款目前口碑不错的耳夹式骨传导耳机&#…

windows下使用cd命令切换到D盘的方法

windows下使用cd命令切换到D盘的方法 winr输入cmd进入终端

【CANFD详细介绍与CAN区别】

在汽车领域&#xff0c;随着人们对数据传输带宽要求的增加&#xff0c;传统的CAN总线由于带宽的限制难以满足这 种增加的需求。此外为了缩小CAN网络&#xff08;max. 1MBit/s&#xff09;与FlexRay(max.10MBit/s)网络的带宽差距&#xff0c;BOSCH公司推出了CAN FD。 CAN FD&…

基于控制屏障函数的安全关键系统二次规划(适用于ACC)(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 基于控制屏障函数的安全关键系统二次规划&#xff08;适用于ACC&#xff09;是一种用于自适应巡航控制&#xff08;ACC&#x…

Servlet文档2

servlet文档2 HttpServletRequest 获取请求头API getMethod()获取请求的方式getRequestURI()获取请求的uri&#xff08;相对路径&#xff09;getRequestURL()获取请求的url&#xff08;绝对路径&#xff09;getRemoteAddr()获取请求的地址getProtocol()获取请求的协议getRem…

Vue3 CSS v-bind 计算和三元运算

官方文档 中指出&#xff1a;CSS 中的 v-bind 支持 JavaScript 表达式&#xff0c;但需要用引号包裹起来&#xff1a; 例子如下&#xff1a; <script lang"ts" setup> const treeContentWidth ref(140); </script><style lang"less" scop…

mschart Label Formart显示数值的格式化

默认这个数值想显示2位小数&#xff0c; 格式化代码如下。 series1.Label "#VAL{###.###}";

字符指针?指针数组?数组指针?《C语言指针进阶第一重奏》

目录 一.字符指针 1.1字符指针的认识 1.2字符指针存放字符串 1.3字符指针的使用 二.指针数组 2.1指针数组的认识 三.数组指针 3.1数组指针的认识 3.2数组名和&数组名的区别 3.3数组指针的使用 3.4数组参数&#xff0c;指针参数 3.5一维数组传参 3.6二维数组传…

如何让Stable Diffusion正确画手(1)-通过embedding模型优化图片质量

都说AI画手画不好手&#xff0c; 看这些是我用stable diffusion生成的图片&#xff0c;小姐姐都很漂亮&#xff0c;但手都千奇百怪&#xff0c;破坏了图片的美感。 其实只需要一个提示词&#xff0c;就能生成正确的手部&#xff0c;看这是我重新生成的效果&#xff0c;每一个小…

【leetcode】面试题 02.01. 移除重复节点 (python + 链表)

题目链接&#xff1a;[leetcode] 面试题 02.01. 移除重复节点 # Definition for singly-linked list. # class ListNode(object): # def __init__(self, x): # self.val x # self.next Noneclass Solution(object):def removeDuplicateNodes(self, he…

MySQL为什么采用B+树作为索引底层数据结构?

索引就像一本书的目录&#xff0c;通过索引可以快速找到我们想要找的内容。那么什么样的数据结构可以用来实现索引呢&#xff1f;我们可能会想到&#xff1a;二叉查找树&#xff0c;平衡搜索树&#xff0c;或者是B树等等一系列的数据结构&#xff0c;那么为什么MySQL最终选择了…