使用重复参数而不是链接过滤器时,如何使用 Q 对象进行 AND 查找?
Posted
技术标签:
【中文标题】使用重复参数而不是链接过滤器时,如何使用 Q 对象进行 AND 查找?【英文标题】:How can I do AND lookups with Q objects when using repeated arguments instead of chaining filters? 【发布时间】:2016-01-19 22:01:12 【问题描述】:我意识到我的问题更简单,我将保留上一个问题的正文作为进一步的解释。我在使用 Q 对象进行 AND 查询时遇到问题。它是如何工作的?我提供了 4 个示例,我唯一可以让它工作的时间是在链接过滤器时,但是我想避免这种情况,以使用 OR 构建更复杂的查询。
在对同一个查询参数进行“与”运算时,我在跨与 Q 对象的关系进行查询时遇到问题。
稍微修改 Django 文档页面上的示例:“博客”模型与“作者”模型具有 m2m 关系。假设我要查询满足以下条件的所有博客:Bob 和 Mary 是作者或 Steve 是作者。我很确定这样做的唯一方法是使用 Q 对象,所以我将它分解成块。这是我迄今为止尝试过的:
Blog.objects.filter(Q(author__name='bob', author__name='mary'))
返回 SyntaxError:关键字参数重复
Blog.objects.filter(Q(author__name='bob') & Q(author__name='mary'))
返回一个空的查询集
Blog.objects.filter(author__name='bob', author__name='mary')
返回 SyntaxError:关键字参数重复
Blog.objects.filter(author__name='bob').filter(author__name='mary')
返回正确的结果,但是,现在我失去了使用 Q 对象作为 OR 参数的能力(我相信),所以我必须进行另一个查询并将结果放在 2 个查询集中,这是不希望的
我不确定我是否正确解释了我的情况,或者我是否以正确的方式进行处理。有人有什么建议吗?
【问题讨论】:
看起来像 ***.com/questions/5301996/… 的副本 试试这个 Blog.objects.filter((Q(author__name='bob') & Q(author__name='mary')) | Q(author__name='steve')) @solarissmoke 不幸的是,这个答案基本上是我的第四个例子。我正在链接过滤器,除非我运行另一个查询,否则我无法执行 OR。 @ManjunathSatyamurthy 它总是返回 OR 参数,因为左边是我的第二个例子,它总是返回空。 @spanishgeek 不确定当您说您必须进行另一个查询/将结果放在两个查询集中时是什么意思?您的第四个(链式)查询将返回 one 查询集,该查询集匹配所有以 Bob 和 Mary 作为作者的书籍。 【参考方案1】:因此,您似乎不能使用 Q 对象来 AND 相同的参数,即使它处于 M2M 关系中。我找到了一个solution on Reddit 基本上用链式过滤器构造多个查询,然后将它们 OR 在一起,从而消除了对 Q 对象的需要:
b1 = Blog.objects.filter(authors__name='bob').filter(authors__name='mary')
b2 = Blog.objects.filter(authors__name='steve')
qs = b1 | b2
【讨论】:
【参考方案2】:我相信这应该可行:
Blog.objects.annotate(author2=author).filter(Q(author__name='bob') & Q(author2__name='mary'))
【讨论】:
这适用于这个特定的例子,我不确定是发布我的问题的通用版本还是完整的东西。我正在尝试动态创建查询,这就是我想使用 Q 对象的原因,所以我可以附加 & 或 |取决于我需要什么。 这是通用的(使用 Q 对象)。当您在 Q 查找中两次使用相同的字段时,它假定您指的是相同的元素。否则,将无法执行以下操作:Blog.objects.filter(Q(author__firstname='bob') & Q(author__lastname='smith'))
如果它按您的意愿工作,它将匹配某个作者的名字为 bob 而另一个作者的姓氏为 smith 的任何博客,这可能不是您想要的.
这就是我的想法,这更多的是我的理解问题,而不是 Q 对象的实际限制。幸运的是,我能够找到适合我需要的东西!以上是关于使用重复参数而不是链接过滤器时,如何使用 Q 对象进行 AND 查找?的主要内容,如果未能解决你的问题,请参考以下文章
Django/Python DRY:使用 Q 对象和模型属性时如何避免重复代码
为啥我们更喜欢在角度中使用 $q 而不是 $http [重复]
使用FFmpeg concat过滤器而不是协议,不同的结果[重复]