Вопрос:
У меня три модели:
class model_A(models.Model): data_1 = models.CharField(max_length=60) data_2 = models.SmallIntegerField() data_3 = models.IntegerField(blank=True, null=True) class model_B(models.Model): data_a = models.ForeignKey(model_A) data_1 = models.CharField(max_length=5) data_2 = models.IntegerField() class model_C(models.Model): data_a = models.ForeignKey(model_A) data_1 = models.CharField(max_length=5) data_2 = models.IntegerField()
так как вы можете видеть, что между model_B → model_A и model_C → model_A, это очень просто.
Мне нужно сделать JOIN из этих трех таблиц с предложением WHERE, поэтому с RAW SQL это будет:
SELECT * FROM ‘model_A’ JOIN ‘model_B’ ON ‘model_A’.’data_1′ = ‘model_B’.’data_a’ JOIN ‘model_C’ ON ‘model_A’.’data_1′ = ‘model_C’.’data_a’ WHERE ‘model_B’.’data_1′ = 1 AND ‘model_C’.’data_1′ = 1
Как я могу создать JOIN из этих трех таблиц (используя оператор filter (предложение WHERE)) с помощью Django ORM?
Возможный дубликат? Дублированный вопрос о том, что кто-то связан, соединяется с TWO-таблицами, что легко решить с помощью select_related(). Но это не работает (или я не знаю, как использовать его в этой ситуации) с тремя таблицами.
Лучший ответ:
Конечно, это не совсем хорошее определение модели, поэтому сначала исправьте это:
from django.db import models class Artist(models.Model): name = models.CharField(max_length=60) year_established = models.SmallIntegerField() votes = models.IntegerField(blank=True, null=True) class Song(models.Model): artist = models.ForeignKey(Artist, related_name=’songs’) title = models.CharField(max_length=5) votes = models.IntegerField() class Fan(models.Model): artist = models.ForeignKey(Artist, related_name=’fans’) name = models.CharField(max_length=5) votes_casted = models.IntegerField()
Теперь позвольте получить всех художников, которые написали песню о любви и имеют поклонников, которые набрали не менее 100 голосов:
queryset = Artist.objects.select_related( ‘songs’, ‘fans’ ).filter(songs__title__icontains=’love’, fans__votes_casted__gte=100)
Обратите внимание, что select_related не играет роли в запросе: это оптимизация для минимизации запросов при итерации набора.
Дальнейшее чтение:
Изменение: добавлено select_related. Это должно теоретически работать и сокращать запросы, но если это не так, я загляну в нее завтра.
Ответ №1
Попробуй это
query_set = model_A.objects.filter(modelb__data_1=1, modelc__data_1=1)
Для данных модели B
query_set = model_B.objects.filter(data_1=1, data_a__modelc__data_1=1)
Надеюсь, это поможет вам