在跨度关系中使用 Q 过滤

Posted

技术标签:

【中文标题】在跨度关系中使用 Q 过滤【英文标题】:Filter with Q inside a span relationship 【发布时间】:2016-07-30 05:55:35 【问题描述】:

我尝试在他们所属的项目的上下文中获取任务。通过一个简单的 Project.objects.all() 我得到了我想要的东西。我怎样才能以最好的方式过滤这个查询集?

型号:

class Project(models.Model):
    projectname_text = models.CharField('Projectname', unique=True, max_length=200)

class Task(models.Model):
    project = models.ForeignKey(Project, on_delete=models.CASCADE, 
                                related_name='tasks')
    author = models.ForeignKey(User, null=True, blank=True, related_name='author')
    editor = models.ForeignKey(User, null=True, blank=True, related_name='editor')

我尝试使用 Q,但结果看起来它包含太多项目,甚至包含 request.user 错误的项目。也许在这里使用 Q 是错误的方法?

视图中的查询:

project_list = Project.objects.filter(Q(tasks__author=request.user) | 
                                      Q(tasks__editor=request.user))

模板:

% for project in project_list %
  html
  % for task in project.tasks.all %
    html
  % endfor %
% endfor %

【问题讨论】:

【参考方案1】:

首先,您的查询条件错误。 authoreditor 在模型 Task 而不是 Project,所以你应该这样做:

projects = Project.objects.filter(Q(tasks__author=request.user) |
                                  Q(tasks__editor=request.user))

其次,永远不要使用list作为你的变量名,因为这会覆盖默认的python数据结构list,所以你不能再使用list()在你的变量声明之后创建一个列表。

【讨论】:

我实际上使用了“project_list = Project.objects.filter(Q(tasks__author=request.user) | Q(tasks__editor=request.user))”,因为Task中的related_name='tasks'模型。我刚刚复制了一个错误的版本-.-,感谢列表提示。结果仍然很奇怪,我得到的项目数量错误,任务数量错误,作者不是 request.user。 :x 你真正想要的是什么?您当前的方法是:获取任务作者为request.user 或任务编辑者为request.user 的所有项目。如果您只想要作者作为 request.user 而不是编辑者的任务,为什么要添加第二个 Q 查询? 当我使用“project_list = Project.objects.all()”时,我可以在我的模板中对所有项目进行迭代,并在其下方添加属于项目的所有任务。现在我想过滤该视图以仅显示登录用户是编辑或作者的任务。 那么我的建议就是这样做的。您之前说过i get the wrong amount of projects with the wrong amount of task with authors that are not the request.user 听起来您只检查作者是否为request.user 也许你得到了重复,你可以做projects = projects.distinct()去重复。

以上是关于在跨度关系中使用 Q 过滤的主要内容,如果未能解决你的问题,请参考以下文章

当多个输入可以为空时,在 Django 中使用 Q 进行过滤

Django过滤查询和或

使用 Q 对象过滤多个 ForeignKey 匹配

使用 F 和 Q 表达式进行 Django 模型过滤

使用多个术语和 Q 过滤器对 reduce 查询进行排序

使用 Q 过滤 django 数据