【问题标题】:Django multiple queries with foreign keysDjango使用外键进行多个查询
【发布时间】:2019-03-15 00:11:35
【问题描述】:

假设我有两个不同的应用程序:

teacher/models.py:

  Teacher(models.Model):
     name = models.CharField(max_length=300)


class/models.py:

  Class(models.Model):
     name = models.CharField(max_length=300)
     teacher = models.ForeignKey(Teacher)
     students = models.ManyToManyField(Student)

我想让所有的老师都有课程和所有的课程。

我想要的结果:

{[
   teacher: '3L' #Teachers Id
   classes: ['20L','14L','30L'] #list of Class objects or ids with the above teacher
],
[# similar to above]

}

这可能吗?这就是我目前正在做的事情:

classes = Class.objects.all()
teachers = Teacher.objects.filter(id__in=classes.value_list('teacher',flat=True).distinct())
for teacher in teachers:
    classes_for_teachers = classes.objects.filter(teacher=teacher)

在上面的代码中,有四个使用循环进行的查询,这肯定会增加时间复杂度。有没有更好的解决方案?提前致谢。

【问题讨论】:

    标签: python mysql django prefetch


    【解决方案1】:

    使用prefetch_related:

    teachers = Teacher.objects.prefetch_related('class_set')
    
    # what you want is not a valid Python structure (set of lists (looking like dicts))
    # list of dicts makes more sense
    result = [
        {'teacher': t.pk, 'classes': t.class_set.all()}
        for t in teachers
    ]
    

    无论有多少教师和班级,这只会触发 2 个数据库查询。

    【讨论】:

    • 什么是class_set?是类列表吗?
    • {modelname}_set 是默认的related_name,您可以通过它访问反向关系的管理器。
    • 我们可以删除那些在同一查询中没有课程的教师的空列表吗?因为循环遍历它们也会增加时间复杂度。
    • 我们可以自定义查询类作为 prefetch_related 的参数吗?
    • 是的,您可以传递给它一个Prefetch object,它可以包含对相关模型的自定义查询。您应该阅读答案中的链接文档 =)
    猜你喜欢
    • 2016-12-26
    • 2012-05-22
    • 2018-03-23
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 2022-10-25
    • 2013-07-24
    • 2011-02-01
    相关资源
    最近更新 更多