Как подключиться к трех таблицам с помощью Django ORM с предложением WHERE

Вопрос: У меня три модели: 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, это очень

Вопрос:

У меня три модели:

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)

Надеюсь, это поможет вам

Оцените статью
Добавить комментарий