python - Django ORM“|” 操作员返回重复项
问题描述
假设我有一个看起来像这样的模型类:
class User:
...
projects = models.ManyToManyField(Project, blank=True)
subscribed_projects = models.ManyToManyField(Project, blank=True)
我有一些返回两个查询集内容的视图逻辑:
return self.request.user.projects.all() | self.request.user.subscribed_projects.all()
在我的特定场景中,假设同一个项目不会同时出现在两者中。
以下是其中一位用户的当前关系:
>>> me = User.objects.get(id=1)
>>> me.projects.all()
<QuerySet [<Project: A>, <Project: B>, <Project: C>, <Project: D>, <Project: E>]>
>>> me.subscribed_projects.all()
<QuerySet [<Project: F>]>
这是我无法解释的部分:
>>> me.projects.all() | me.subscribed_projects.all()
<QuerySet [<Project: A>, <Project: B>, <Project: C>, <Project: D>, <Project: D>, <Project: E>, <Project: F>]>
项目“D”在这里出现了两次,即使它只出现在其中一个查询集中!
现在,我可以通过添加distinct()
或使用union()
来实现我想要的行为,但为什么会这样呢?
解决方案
projects
和subscribed_projects
是两个不同的多对多关系Project
,因此当从它们查询一个时,存在与不同中间表的连接。虽然我不知道查询集__or__
运算符的确切内部工作方式,但由于您没有收到错误,我只能假设它将使用组合查询中两个表的连接。
从上面的分析可以得出结论,你最终会连接多个表,因为很明显,多个表的连接很容易引入重复的结果。如您所知, usingdistinct
可以为您解决此问题(不建议使用union
,因为那样会限制您可以对联合查询进行的可能过滤器):
queryset = me.projects.all() | me.subscribed_projects.all()
queryset = queryset.distinct()
推荐阅读
- ruby - Ruby 中的“超级”和继承
- r - 提取唯一值并使用索引键存储
- ruby-on-rails - Ruby-on-Rails 添加 current_page?到我的link_to
- python - 如何通过指定列名获取所需的列数据
- java - 以破坏性方式从 WebSphere 读取消息
- ios - 表视图:无法使用“[String]”类型的索引为“[String]”类型的值下标
- python - Python:在字符串中查找确切的短语
- javascript - 如何为使用 Vuex 商店的 Vue 表单组件编写 Jest 单元测试?
- neural-network - Pytorch Forward Pass 每次都改变?
- jhipster - JHipster Generator v4.14 未显示 React 选项