如何在多个Django模型上进行JOIN

时间:2017-04-12 09:37:42

标签: python mysql django join

给出以下模型:

class Copy(CommonLibraryBaseModel):
    lecture = models.ForeignKey('Lecture', ...)
    signature = models.CharField(max_length=100, ...)

class Lecture(CommonLibraryBaseModel):
    category = models.ForeignKey('LectureCategory', ...)

class LectureCategory(CommonLibraryBaseModel):
    parent = models.ForeignKey('self', ...)
    display_name = models.CharField(max_length=100, ...)

我基本上想要进行以下查询:

SELECT signature, display_name FROM lecturecategory as lc, lecture as l, copy as c WHERE lc.id = l.category_id AND c.lecture_id = l.id AND lc.parent_id=2;

我如何在Django中这样做?我无法弄清楚如何组合不同的模型。

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

SELECT signature, display_name
FROM lecturecategory as lc, lecture as l, copy as c
WHERE lc.id = l.category_id AND c.lecture_id = l.id AND lc.parent_id=2;

将是:

Copy.objects.filter(lecture__category__parent_id=2).values_list('signature', 'lecture__category__display_name')

如果您想在结果中使用字典的QuerSet,请使用values而不是values_list。 Values_list返回一个元组。 Documentation about lookup relationship

答案 1 :(得分:0)

您可以使用以下过滤器获取Copy个实例的查询集

copies = Copy.objects.filter(lecture__category_parent_id=2)

有关详细信息,请参阅lookups that span relationships上的文档。

然后,您可以遍历查询集,并使用外键访问相关的讲座和讲座类别。

for copy in copies:
    print(copy.signature, copy.lecture.category.display_name)

最后,您可以将初始查询更改为使用select_related,以便Django使用内部联接来获取讲座和类别,而不是单独的查询:

copies = Copy.objects.filter(lecture__category_parent_id=2).select_related('lecture', lecture__category')