首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >跨越多值关系

跨越多值关系
EN

Stack Overflow用户
提问于 2021-09-19 19:16:27
回答 1查看 49关注 0票数 3

我阅读了django文档,发现了一些令人困惑的东西!https://docs.djangoproject.com/en/3.2/topics/db/queries/#spanning-multi-valued-relationships

据说,“当您基于ManyToManyField或反向ForeignKey筛选对象时,您可能会对两种不同类型的筛选器感兴趣”。

为了选择所有在标题中包含两个“Lennon”的条目并于2008年发布的博客(满足这两种条件的相同条目),我们将这样写:

代码语言:javascript
复制
Blog.objects.filter(entry__headline__contains='Lennon', entry__pub_date__year=2008)

为了选择所有在标题中包含“列侬”条目的博客,以及2008年发表的文章,我们会写:

代码语言:javascript
复制
Blog.objects.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008)

假设只有一个博客同时包含“Lennon”和2008年的条目,但2008年的条目中没有一个包含“Lennon”。第一个查询不会返回任何博客,但是第二个查询将返回该博客。

因此,通过阅读本指南,我的脑海中产生了多个问题:

这两种过滤的区别是什么?我所知道的是,他们都必须返回的博客,其中包含两个‘列侬’的标题,并于2008年出版。我找不出重点。

文档中说,这条规则只适用于ManyToManyField或反向ForeignKey。问题是,为什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-19 19:23:26

这两种过滤的区别是什么?

假设您有一个包含两个(或更多)条目的Blog。其中一个条目的标题是一些包含单词'Lennon'的文本,但不是在2008年编写的,此外,博客的标题中没有'Lennon'这个词,而是在2008年写的。

第一个带有.filter(entry__headline__contains='Lennon', entry__pub_date__year=2008)的查询查找标题中包含'Lennon'的条目,该条目应该在2008年编写。对于我们在第一段中定义的样本数据,这意味着没有选择这个Blog,因为这两个条件适用于同一个条目。

另一方面,如果您将其写为.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008),Django将生成两个LEFT OUTER JOIN,这意味着它将查找一个博客,其中一个条目包含一个包含Lennon的标题,一个条目(可以是不同的条目,也可以是相同的条目)已经在2008年编写。因此,这将检索第一段中定义的Blog

文档说,这条规则只适用于ManyToManyField或反向ForeignKey。问题是,为什么?

因为反向ForeignKey是一对多的关系,而ManyToManyField是多到多的关系.…-to-many在这里很重要。如果这是一个…-to-one,那么就不可能用两个或多个条目创建一个Blog:如果一个Blog有一个ForeignKey到一个Entry模型,那么这意味着博客只能有一个条目,而不是多个条目。由于这样限制了条目的数目,所以不可能有两个或多个条目,因此过滤不会区分这两种情况。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69246373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档