Django rest_framework 条件过滤 queryset.filter用法和 django_filters.FilterSet用法

news/2025/3/30 14:16:53/文章来源:https://www.cnblogs.com/emanlee/p/18301252

django 条件过滤 queryset.filter用法和 django_filters.FilterSet用法

 

 

1 queryset.filter用法

__exact 精确等于 like 'aaa'
 __iexact 精确等于 忽略大小写 ilike 'aaa'
 __contains 包含 like '%aaa%'
 __icontains 包含 忽略大小写 ilike '%aaa%',但是对于sqlite来说,contains的作用效果等同于icontains。
__gt 大于
__gte 大于等于
__lt 小于
__lte 小于等于
__in 存在于一个list范围内
__startswith 以...开头
__istartswith 以...开头 忽略大小写
__endswith 以...结尾
__iendswith 以...结尾,忽略大小写
__range 在...范围内
__year 日期字段的年份
__month 日期字段的月份
__day 日期字段的日
__isnull=True/False

如果参数是字典,如

condtions: {'date__lt': '2018-05-22','status': '未支付','name__exact': 'yangxia'}

 Entry.objects.filter(**condtions)相当于 Entry.objects.filter(date__lt= '2018-05-22',status='未支付',name__exact='yangxia')

翻译成sql语句是

select * from  Entry.objects where date<='2018-05-22' and status='未支付' and name like 'yangxia'


filter例子:
>> q1 = Entry.objects.filter(headline__startswith="What")
>> q2= q1.filter(pub_date__gte=datetime.date.today())
>>> q3= q.filter(pub_date__lte=datetime.date.today())

 

2 django_filters.FilterSet用法

from django_filters import rest_framework as django_filters
class RobotFilter(django_filters.FilterSet):
   robot_id = django_filters.CharFilter(field_name='id')
   machine_id = django_filters.CharFilter(field_name='machine_id')
   city = django_filters.CharFilter(field_name='city')
   # lookup_expr(可选)为判断条件,field_name(必选)为模型类属性,created_time查询字符串
   created_time = django_filters.CharFilter(field_name='created_at', lookup_expr='startswith')
   created_start_time = django_filters.DateTimeFilter(field_name='created_at', lookup_expr='gt')
   created_end_time = django_filters.DateTimeFilter(field_name='created_at', lookup_expr='lt')
   problem_isnull = django_filters.BooleanFilter(field_name='problem', lookup_expr='isnull')
   name = django_filters.CharFilter(lookup_expr='iexact')  # iexact表示精确匹配, 并且忽略大小写
   author = django_filters.CharFilter(lookup_expr='icontains')  # icontains表示模糊查询(包含),并且忽略大小写
   price = django_filters.NumberFilter(look_expr='exact')  # exact表示精确匹配
   age_g = filters.NumberFilter(field_name='age', lookup_expr='gte',help_text="年龄大等于")
   age_l = filters.NumberFilter(field_name='age', lookup_expr='lte',help_text="年龄小等于")
   # opensea是一个外键
   town = filters.CharFilter(field_name='opensea__home_town',lookup_expr='icontains',help_text="户籍地")
   exp = filters.CharFilter(method='get_exp_work_display',help_text="职位匹配")
   def get_exp_work_display(self, queryset, *arg):
       word = arg[1]
       # MySeaMid.objects.filter(user=self.request.user, sea_type=0).order_by('-add_time')
       queryset = queryset.filter(Q(opensea__worker__icontains=word) | Q(opensea__job_exp__icontains=word))
       return queryset
   task_res_state = django_filters.CharFilter(method="get_task_res_state")   def get_task_res_state(self, queryset, *arg): #多选情况
      if str(arg[1]) == "0":  # arg[1]=('task_res_state', '0')
         task_res = (1, 2, 3)
      else:
         task_res = (0, 4, 5, 6)
      print(task_res)
      queryset = queryset.filter(task_res__in=task_res)
      return queryset   class Meta:
      model = Robot
      fields = ['robot_id', 'machine_id', "city", "created_start_time", "created_end_time", 'created_time',
              'firmware_version', 'state', "robot_type", "hardware_version", "exist_map", 'task_res_state']

转自:https://blog.csdn.net/weixin_38836909/article/details/112611214

======================================================

 当使用复杂的ORM方式查询时,如果有困惑,使用 str(queryset.query) 查看对应生成的SQL语句。
聚合和其他 QuerySet 子句
filter() 和 exclude()

聚合结果也可以使用过滤。任何应用于普通模型字段的 filter() (或 exclude())对聚合的对象也有约束效果。

当与 annotate() 子句一起使用时,过滤器的效果是限制用来计算“注释”( annotate() 子句会给queryset中的对象增加一个属性和值,称之为“注释”)的对象。

例如,以下查询生成所有标题以 “Django” 开头的书籍的带注释列表:

>>> from django.db.models import Avg, Count
>>> Book.objects.filter(name__startswith="Django").annotate(num_authors=Count("authors"))


当与 aggregate() 子句一起使用时,过滤器的效果是限制用来计算聚合的对象。

例如,以下查询生成所有标题以 “Django” 开头的书籍的平均价格:

>>> Book.objects.filter(name__startswith="Django").aggregate(Avg("price"))

过滤注释

注解过的值也可以使用过滤器。注解的别名可以和任何其他模型字段一样使用 filter()和 exclude()子句。(因为使用 annotate()生成的也是一个QuerySet,根据链式查询的规则,是可以这样的。)
例如,要生成一个具有多位作者的书籍列表:

>>> Book.objects.annotate(num_authors=Count("authors")).filter(num_authors__gt=1)


annotate() 和 filter() 子句的顺序

当开发一个涉及 annotate() 和 filter() 子句的复杂查询时,要特别注意应用于 QuerySet 的子句的顺序。

当一个 annotate() 子句应用于查询,会根据查询状态来计算注释。这实际上意味着 filter() 和 annotate() 不是可交换的操作。

filter()用在前面,会先过滤对象,再生成注释。
annotate()用在前面,会先生成注释,然后过滤对象,在多对多的查询和一对多的反向查询时,会容易观察到差异。例如:

    出版者A有两本评分4和5的书。
    出版者B有两本评分1和4的书。
    出版者C有一本评分1的书。
    以下是一个使用 Count 聚合的示例:

>>> a, b = Publisher.objects.annotate(avg_rating=Avg("book__rating")).filter(
...     book__rating__gt=3.0
... )
>>> a, a.avg_rating
(<Publisher: A>, 4.5)  # (5+4)/2
>>> b, b.avg_rating
(<Publisher: B>, 2.5)  # (1+4)/2

>>> a, b = Publisher.objects.filter(book__rating__gt=3.0).annotate(
...     avg_rating=Avg("book__rating")
... )
>>> a, a.avg_rating
(<Publisher: A>, 4.5)  # (5+4)/2
>>> b, b.avg_rating
(<Publisher: B>, 4.0)  # 4/1 (book with rating 1 excluded)

   

第一个查询请求至少有一本评分3以上的书籍的出版者的书籍平均分。第二个查询只请求评分3以上的作者书籍的平均评分。
order_by()

annotate() 子句之后可以用order_by()排序,因为注释相当于查询对象结果的一个属性了。
例如,要按参与书籍创作的作者数量对书籍的 QuerySet 进行排序:

>>> Book.objects.annotate(num_authors=Count("authors")).order_by("num_authors")


values()

通常,注解值会添加到每个对象上,即一个被注解的 QuerySet 将会为初始 QuerySet 的每个对象返回一个结果集。然而,当使用 values() 子句来对结果集进行约束时,生成注解值的方法会稍有不同。不是在原始 QuerySet 中对每个对象添加注解并返回,而是根据定义在 values() 子句中的字段组合先对结果进行分组,再对每个单独的分组进行注解,这个注解值是根据分组中所有的对象计算得到的。
通过一个例子对比一下:
查询每个作者所著书的平均评分:

>>> Author.objects.annotate(average_rating=Avg("book__rating"))


使用了values("name")

Author.objects.values("name").annotate(average_rating=Avg("book__rating"))


在这个例子中,作者会按名字分组,所以你只能得到不重名的作者分组后计算出的注释值。如果数据中有两个作者同名,那么他们原本各自的查询结果将被合并到同一个结果中;两个作者的所有评分都将被计算为一个平均分。
annotate() 和 values() 的顺序

和使用 filter() 一样,作用于某个查询的 annotate() 和 values() 子句的顺序非常重要。如果 values() 子句在 annotate() 之前,就会根据 values() 子句产生的分组来计算注解。

然而如果 annotate() 子句在 values() 之前,就会根据整个查询集生成注解。然后 values() 子句只能限制输出的字段。例如:

>>> Author.objects.annotate(average_rating=Avg("book__rating")).values(
...     "name", "average_rating"
... )


这段代码将为每个作者添加一个唯一注释,但只有作者姓名和 average_rating 注释会返回在输出结果中。
和 order_by() 一起用会发生化学反应

这里需要注意的一点是order_by()会影响分组。
聚合所生成的注释

你也可以在生成的注释结果上生成聚合。例如,如果您想计算每本书的平均作者数量,您首先要用作者数量对书籍集进行注释,然后对该作者数量进行聚合:

>>> from django.db.models import Avg, Count
>>> Book.objects.annotate(num_authors=Count("authors")).aggregate(Avg("num_authors"))
{'num_authors__avg': 1.66}

  

在空查询集或组上进行聚合操作时,需要格外小心,因为这可能会导致未定义的行为或错误。在执行聚合操作之前,通常应确保查询集或组中包含足够的数据以执行所需的聚合计算。如果查询集或组为空,可以使用条件语句来避免聚合错误或不必要的操作。

当对空的查询集或分组应用聚合操作时,结果通常默认为其 default 参数,通常是 None。这种行为发生是因为当执行的查询不返回任何行时,聚合函数会返回 NULL。
                     
原文链接:https://blog.csdn.net/chengyikang20/article/details/136474554

======================================================

 source: https://blog.csdn.net/qq_33867131/article/details/82754778
1、filter() 将满足条件的数据提取出来
取出id大于2 且 id不等于3 的图书
books = Book.objects.filter(id__gte=2).filter(~Q(id=3))

2、exclude() 将满足条件的数据剔除
books = Book.objects.filter(id__gte=2).exclude(id=3)

3、order_by() 将满足条件的数据进行排序
articles = Article.objects.filter(title='2').order_by('-create_time')

4、values(): 指定返回哪些字段,返回值是:字段和值形成的字典{"title":"xxx", "content":"xxx"}
(1)获取图书的id,name和作者表中的,作者名(Book和Author表外键连接)
books = Book.objects.values("id", "name", "author__name")
=======>>想要给 作者名,换个名字
books = Book.objects.values("id", "name", author_name=F("author__name"))

(2)获取每本书的销量(这里和annotate场景类似,感觉这样更好用一点)
books = Book.objects.values("id", "name", sales=Count("bookorder__id"))

5、values_list(): 用法和values()一样,但是返回值是元组('xxx', 'xxx')
books = Book.objects.values_list("name", flat=True) =====>> 返回结果:红楼梦
如果只指定一个字段,那么我们可以指定'flat=True',这样返回回来的结果就不再是一个元组,而是这个
字段的值,'flat=True'只能用在一个字段的情况下,否则会报错!!!

6、select_related():提取某个模型的数据的同时,也提前将相关联的数据提取出来(只能用在一对多或者一对一中)
获取图书的作者(Book和Author表外键连接)
(1)先得到图书表的所有数据,再 . 出作者(这个方法很耗性能,每 . 一下,就会执行一次查询语句)
books = Book.objects.all()
for book in books:
print(book.author.name)

(2)查出图书表的所有信息和关联表中作者的所有信息,存储在内存中,再取时就直接从内存中去取,而不用再
执行sql语句,大大优化了性能
books = Book.objects.select_related("author")
for book in books:
print(book.author.name)

7、prefetch_related():这个方法和select_related非常的类似,就是在访问多个表中的数据的时候,
减少查询的次数(只能用在多对一和多对多中)
(1)先查找出所有的图书信息 --> 再查出每本书的订单信息(每一次bookorder_set,都会执行一次查询语句)
# 先查找出所有的图书信息
books = Book.objects.all()
for book in books:
# 再查出每本书的订单信息
orders = book.bookorder_set.all()
for order in orders:
print(order.id)

(2)查找出所有的图书信息和查出每本书的订单信息存储在内存当中
books = Book.objects.prefetch_related("bookorder_set")
for book in books:
orders = book.bookorder_set.all()
for order in orders:
print(order.id)

8、
defer 过滤掉指定的字段,返回值不是字典,而是模型
only 只提取指定的字段,返回值不是字典,而是模型
articles = Article.objects.defer("title")
articles = Article.objects.only("title")

9、
first() 获取第一条数据
last() 获取最后一条数据

10、exists 如果要判断某个条件的元素是否存在,那么建议使用exists
if Book.objects.filter(name__contains='红楼梦').exists():
print(True)
比使用count更高效:
if Book.objects.filter(name__contains='红楼梦').count() > 0:
print(True)
也比直接判断QuerySet更高效:
if Book.objects.filter(name__contains='红楼梦'):
print(True)

11、distinct() :去除掉重复数据
提取所有销售的价格超过80元的图书,并且删掉那些重复的数据
books = Book.objects.filter(bookorder__price__gte=80).distinct()

12、QuerySet 切片操作
books = Book.objects.all()[1:3]
books = Book.objects.all()[1:3:2] (第三个参数为步长)

======================================================

 

======================================================

 

======================================================


 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CF708E Students Camp

先设 \(D(i)\) 表示 \(k\) 次吹风中 \(i\) 次成功吹在特定行的概率,有 \[D(i)={k \choose i}p^i(1-p)^{k-i} \]设 \(P(l,r)\) 表示某一行只剩下 \((l,r)\) 的砖块的概率,由于左右两边显然独立,于是我们有: \[P(l,r) =D(l-1)D(m-r) \]再设 \(f(i,l,r)\) 表示第 \(i\) 行剩下…

2025.3.27 鲜花

如何优雅的使用 stl如何优雅的使用 stl啥背景,杀乌鸡 ``` Viumbe vyote vya mungu wetu na mfalme wetu Pazeni sauti ili nasi mwimbe Pazeni sauti ili nasi mwimbe Pazeni sauti Pazeni sauti Viumbe vyote vya mungu wetu na mfalme wetu Pazeni sauti ili nasi mwimbe Pa…

读DAMA数据管理知识体系指南32参考数据和主数据概念(下)

读DAMA数据管理知识体系指南32参考数据和主数据概念(下)1. 主数据 1.1. 主数据是有关业务实体(如雇员、客户、产品、金融结构、资产和位置等)的数据,这些实体为业务交易和分析提供了语境信息 1.2. 实体是客观世界的对象(人、组织、地方或事物等)​ 1.3. 实体被实体、实例…

Springboot3+Vue3实现JWT登录鉴权

做鉴权原因: 管理系统的数据是敏感的,隐私的,每个角色的权限是不同的,必须在数据的增删改查操作时候对访问的用户进行权限验证 JWT(Json Web Token) 用于在网络应用间安全的传递消息。它以紧凑且自包含的方式,通过JSON对象在各方之间传递经过验证的信息。JWT通常由三部分…

搜维尔科技:SenseGlove触觉反馈手套-自动化和培训的突破

触觉力反馈技术领导者SenseGlove和机器人操控创新者Aeon宣布推出HEART项目。此次合作将虚拟现实 、力反馈触觉手套(SenseGlove)和机器人系统(Aeon)集成在一起,以实现直观控制和实时力反馈,使机器人训练更加方便和有效。 自动化和培训的突破 由于产品需求不断变化以及机器…

搜维尔科技:Haption通用遥控控制器,可轻松集成到工业机器人控制中

TeleRobotics EXtender (TREX) 是一个专为力反馈远程操作而设计的框架。它为操作员必须在危险、具有挑战性或受限的环境中操作的情况提供了一种创新的解决方案,使他们能够在不暴露自己风险的情况下执行任务。借助 TREX,操作员可以手动控制远程机器人,具有很高的灵活性和精确…

Elasticsearch 的搜索功能

Elasticsearch 的搜索功能建议阅读顺序:Elasticsearch 入门 Elasticsearch 搜索(本文)1. 介绍 使用 Elasticsearch 最终目的是为了实现搜索功能,现在先将文档添加到索引中,接下来完成搜索的方法。 查询的分类:叶子查询:叶查询子句在特定字段中查找特定值,例如 match、t…

20242213 实验二《Python程序设计》实验报告

20242213 2024-2025-2 《Python程序设计》实验2报告 课程:《Python程序设计》 班级: 2422 姓名: 刘宗林 学号:20242213 实验教师:王志强 实验日期:2025年3月26日 必修/选修: 公选课 1.实验内容设计并编写一个计算器程序,实现基本运算功能;功能包括加、减、乘、除、取余…

《实战Java高并发程序设计(第3版)》 | PDF免费下载

《实战Java高并发程序设计(第3版)》主要介绍基于Java的并行程序设计基础、思路、方法和实战。第一,立足于并行程序基础,详细介绍Java并行程序设计的基本方法。第二,进一步详细介绍JDK对并行程序的强大支持,帮助读者快速、稳健地进行并行程序开发。第三,详细讨论“锁”的…

《DeepSeek原理与项目实战》 | PDF免费下载

DeepSeek 是一种基于 Transformer 架构的生成式 AI(Artificial Intelligence)大模型,融合了MoE 架构、混合精度训练、分布式优化等先进技术,具备强大的文本生成、多模态处理和任务定制化能力。本书系统性地介绍了开源大模型 DeepSeek-V3 的核心技术及其在实际开发中的深度应…

实现极限网关(INFINI Gateway)配置动态加载

还在停机更新 Gateway 配置,OUT 了。 今天和大家分享一个 Gateway 的功能:动态加载配置(也称热更新或热加载)。 这个功能可以在 Gateway 不停机的情况下更新配置并使之生效。 配置样例如下: path.data: data path.logs: logconfigs:auto_reload: true # set true to auto …

ubuntu20.04安装Synergy

问题 最近在Ubuntu20.04上安装新版本的Synergy遇到一些问题,Synergy最后一个支持ubuntu20.04的版本是v3.1.3-beta,下面是下载地址: https://symless.com/synergy/download/other 在安装的时候遇到下面的问题:提示依赖libssl1,然后尝试安装下面的软件包: sudo apt install…