【问题标题】:Django ORM Queryset class behave different with same filtersDjango ORM Queryset 类的行为与相同的过滤器不同
【发布时间】:2019-03-01 23:42:22
【问题描述】:

这是一个简单的问题。

我想使用 Queryset 类一次处理 2 个过滤器。让我解释。

from django.db.models import Q
import datetime
from .models import Asset

query_set = Asset.objects.filter(category__name="car")

date_query = {'eav__date__gte': datetime.datetime(2018, 9, 2, 0, 0), 'eav__date__lte': datetime.datetime(2018, 9, 14, 0, 0)}

number_query = {'eav__price__gte': '60', 'eav__price__lte': '600'}

total_query = {'eav__date__gte': datetime.datetime(2018, 9, 2, 0, 0), 'eav__date__lte': datetime.datetime(2018, 9, 14, 0, 0),'eav__price__gte': '60', 'eav__price__lte': '600'}

query_set = query_set.filter(Q(**number_query))

query_set = query_set.filter(Q(**date_query))

在这种情况下,query_set 为空!


query_set = query_set.filter(Q(**total_query))

在这种情况下,query_set 为空!


有人可以解释一下两个查询之间的区别吗?提前致谢。

【问题讨论】:

  • 你能打印出这两个查询吗(print(str(query_set.query))?我的印象是原来的query_set可能已经不一样了。

标签: django django-models django-queryset django-orm


【解决方案1】:

这是因为您正在过滤多值关系。正如the docs 解释:

Django 处理filter() 调用的方式一致。单个filter() 调用中的所有内容同时应用以过滤出符合所有这些要求的项目。连续的filter() 调用进一步限制了对象集,但对于多值关系,它们适用于链接到主模型的任何对象,不一定是之前的filter() 调用选择的那些对象。

因此,您的第一个案例选择了所有具有符合日期要求的 EAV 和符合价格要求的 EAV 的资产,但不一定是相同的 EAV。您的第二种情况仅选择那些有一个 EAV 同时满足 both 要求的资产。

【讨论】:

  • 这是否假设这两行 query_set = query_set.filter(Q(**number_query)) query_set = query_set.filter(Q(**date_query)) 分别被一一测试?但是如果它们都一个接一个地应用在代码中呢?那不就是&操作吗?
  • 我不明白这个问题。关键是它们在不同的filter() 调用中。
  • 我的意思是逐个运行这两个过滤器是一样的,query_set = query_set.filter(Q(**number_query)).filter(Q(**date_query))?这和在**total_query上过滤一样吗?
  • 但我刚刚解释了为什么它们不一样。
【解决方案2】:

使用 Q 对象构建查询集。 在 Django 中处理查询的最简单方法 在你的情况下

query_set = query_set.filter(Q(**number_query))
query_set = query_set.filter(Q(**date_query))

这些是不同的查询集。

query_set = query_set.filter(Q(**total_query))

在这里,您将两个不带 AND ,OR 条件的查询组合在一起,因此它是空的。 在这里你想要和条件我认为所以使用这个 Q(first_name__startswith='R') & Q(last_name__startswith='D')

【讨论】:

    猜你喜欢
    • 2020-07-06
    • 2015-10-26
    • 2014-07-13
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 1970-01-01
    • 2018-10-09
    • 2013-09-08
    相关资源
    最近更新 更多