Django double join с несколькими моделями?

Я потратил на это довольно много времени и так и не смог понять, как соединить эти таблицы с помощью django.

У меня есть база данных Movie со следующими моделями:

class Movies(models.Model):
MovieName = models.CharField(db_column='MovieName', primary_key=True, max_length=30)  
MovieRating = models.FloatField(db_column='MovieRating') 
MovieReleaseTime = models.DateTimeField(db_column='MovieReleaseTime')  

class Genre(models.Model):
GenreID = models.IntegerField(db_column='GenreID', primary_key=True, max_length=30)
GenreTitle = models.CharField(db_column='GenreTitle', unique=True, max_length=30)

class MovieGenres(models.Model):
MovieName = models.ForeignKey('Movies', models.DO_NOTHING, db_column='MovieName')
GenreID = models.ForeignKey('Genre', models.DO_NOTHING, db_column='GenreID')

В моем PostgreSQL я могу сопоставить MovieName с GenreTitle, используя следующий запрос:

SELECT "MovieName", "GenreTitle"
FROM public."Movies"
NATURAL JOIN public."MovieGenres"
NATURAL JOIN public."Genres";

Затем я получаю что-то вроде этого:

  MovieName | GenreTitle 
 -----------|------------ 
  MovieA    | GenreA     
  MovieA    | GenreB     
  MovieB    | GenreA   

Как я могу добиться такого же результата с помощью представлений Django?

Вы можете сделать это с помощью объектов annotate и F:

qs = MovieGenres.objects.annotate(
    movie_name=F('MovieName__MovieName'),
    genere_title=F('GenreID__GenreTitle'),
).values_list('movie_name', 'genere_title')

print(qs)

Вывод будет

[
    ("MovieA", "GenreA"),
    ("MovieA", "GenreB"),
    ("MovieB", "GenreA"),
    # etc... 
]

Вы можете немного сократить это с помощью:

from django.db.models import F

MovieGenres.objects.values_list(
    movie_name=F('MovieName__MovieName'),
    genere_title=F('GenreID__GenreTitle')
)
Вернуться на верх