【问题标题】:Django queryset filter for backwards related fields用于向后相关字段的 Django 查询集过滤器
【发布时间】:2012-12-03 23:13:39
【问题描述】:

如何根据与之相关的模型过滤模型?下面的示例......这可行,但我认为这会两次命中数据库并且非常不雅。有没有办法直接使用查询集来做到这一点?也许以某种方式使用select_related(),但一直无法弄清楚这一点。我想返回QuerySet 中的Project

from django.db import models

class Person(models.Model):
    pass

class Project(models.Model):
    pass

class Action(models.Model):
    person = models.ForeignKey(Person)
    project = models.ForeignKey(Project)

# Better way to do this?
def projects_by_person(person):
    actions = Action.objects.filter(person=person)
    project_ids = actions.values_list('project')
    return Project.objects.filter(id__in=project_ids)

【问题讨论】:

  • 实际上,这应该只是单个数据库命中,因为过滤器将作为子查询完成。不过,使用 Raunak 建议的双下划线语法是更好的选择。
  • 很高兴知道。连接的执行速度应该比 in (...) 子查询快一点。谢谢!

标签: python django django-queryset


【解决方案1】:

试试这个。我还没有测试过,如果你有任何问题,请告诉我

#Untested Code
Project.objects.filter(action__person = person)

【讨论】:

  • 没有意识到您可以使用相关字段进行过滤。简洁优雅,谢谢!
【解决方案2】:

PersonProject 之间确实存在多对多关系吗?如果是这样,您可以像这样简化设置:

class Person(models.Model):
    projects = models.ManyToManyField('Project')
    name = models.CharField(max_length=100)     # just an example

class Project(models.Model):
    # ... some fields here ...

然后你可以例如发出以下查询以从名为 John 的人那里获取所有项目:

Project.objects.filter(person_set__name="John")

当您有大量查询遵循不同数据库表之间的关系但您不需要它来完成您想要的事情时,使用select_related() 可以加快查找速度。

【讨论】:

  • 谢谢,但 Person 模型并不仅仅与项目相关联。这些模型只是为了给出示例而设计的,没有一堆不相关的样板。
【解决方案3】:

您可以在下面找到我的案例:

有老师和课程。教师可以开设多门课程,但课程只有一位教师完成。

class Course(models.Model):
    teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
    -------

class Teacher(models.Model):
    name = models.CharField(max_length=50)
    ------

在个人教师页面中,我想列出该教师所教授的所有课程。您可以在下面找到相关的视图功能。

def teacher(request, teacher_id):
teacher = get_object_or_404(Teacher, pk=teacher_id)
courses = Course.objects.filter(teacher = teacher)

context = {
    'teacher': teacher,
    'courses': courses
}

【讨论】:

    猜你喜欢
    • 2023-01-16
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    • 2021-10-27
    • 2011-12-05
    • 2020-10-30
    • 2012-11-18
    • 1970-01-01
    相关资源
    最近更新 更多