在三个表之间加入django中的请求并显示所有属性

Posted

技术标签:

【中文标题】在三个表之间加入django中的请求并显示所有属性【英文标题】:Join request in django between three tables and display all attributes 【发布时间】:2022-01-16 22:16:18 【问题描述】:

我有三个模型

class A(models.Model):
    field1 = models.IntegerField()

class B(models.Model):
   id_a = models.ForeignKey(A,on_delete=models.CASCADE)
   field1 = models.IntegerField()
   field2 = models.IntegerField()

class C(models.Model):
   id_a = models.ForeignKey(A,on_delete=models.CASCADE)
   field1 = models.IntegerField()
   field2 = models.IntegerField()

我想写一个如下所示的请求:SELECT * FROM B,C,A WHERE B.id_a=C.id_a WHERE A.id_a=2 并显示所有属性两张桌子这是我尝试做的:

a_id_att = 1
data = B.objects.filter(id_a=C.objects.filter(id_a=a_id_att)[0])

它不起作用。如何编写join和make来显示表的所有属性?

【问题讨论】:

【参考方案1】:

你写的 SQL 语句看起来很奇怪。

SELECT * FROM B, C, A
    WHERE B.id_a = C.id_a
        AND A.id_a = 2

您似乎想要来自A 的单行,然后是来自BC 的所有相关行,而您的SQL 查询无法实现。 你的意思是这样的吗:

SELECT * FROM B, C, A
    WHERE A.id = 2
        AND B.id_a = A.id
        AND C.id_a = A.id

您可以在 Django 中使用prefetch_related() 实现类似的功能,它会构建一个查询,以便在第一个查询中而不是在后续查询中将相关行也加载到内存中。

# this will return a queryset with a single element, or empty
qs = A.objects.prefetch_related('b_set', 'c_set').filter(id=2)

for elem in qs:               # here the single DB query is made
    print(elem.field1)        # A.field1
    for det in elem.b_set.all():
        print(det.field1)     # B.field1, does NOT make another DB query
        print(det.field2)     # B.field2, does NOT make another DB query
    for det in elem.c_set.all():
        print(det.field1)     # C.field1, does NOT make another DB query
        print(det.field2)     # C.field2, does NOT make another DB query

注意:我在这里使用b_set,因为这是ForeignKey 字段的默认值;如果该字段指定不同的related_name,则会发生这种情况。

这是否解决并解决了您的问题?

【讨论】:

注意:您可以使用print(qs.query) 查看将使用的大致(不准确)SQL

以上是关于在三个表之间加入django中的请求并显示所有属性的主要内容,如果未能解决你的问题,请参考以下文章

django在html之间传递变量

mysql查询加入,比较两个表并返回第一个表中的所有记录

Django中HtttpRequest请求

加入多个表并显示从 id 链接的所有名称

如何加入表中的最新记录?

左加入并属于