Запрос на соединение в django между тремя таблицами и отображение всех атрибутов

У меня есть три модели

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 и сделать так, чтобы отображались все атрибуты таблиц?

SQL-запрос, который вы написали, кажется странным.

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

Похоже, что вы хотите получить одну строку из A, а затем все связанные строки из B и C, чего ваш 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.

Решает ли это вашу проблему?

Вернуться на верх