Actor
, Movie
, ActorMovie
(중간테이블) 이렇게 3개의 모델클래스를 만든다.from django.db import models
from django.db.models.base import ModelState
from django.db.models.fields import DateField, IntegerField
class Actor(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
date_of_birth = models.DateField()
class Meta:
db_table = 'actors'
class Movie(models.Model):
title = models.CharField(max_length=20)
release_date = models.DateField()
running_time = models.IntegerField()
class Meta:
db_table = 'movies'
# 중간테이블
class ActorMovie(models.Model):
actor = models.ForeignKey('Actor', on_delete=models.CASCADE)
movie = models.ForeignKey('Movie', on_delete=models.CASCADE)
class Meta:
db_table = 'actors_movies'
중간테이블클래스(소문자)_set
를 사용하여, actor
가 중간테이블
을 역참조한 queryset을 가져온다.movies = actor.actormovie_set.all()
import json
from django.http import JsonResponse
from django.views import View
from movies.models import Actor, Movie, ActorMovie
# actor의 first_name, last_name, 출연한 movies list 반환
class ActorView(View):
def get(self, request):
actors = Actor.objects.all()
results = []
for actor in actors:
# 중간테이블 actormovie 역참조: actormovie_set
movies = actor.actormovie_set.all()
# 이런 방법도 있다. ActorMovie 클래스에서 불러오는 법
# movies = ActorMovie.objects.filter(actor=actor)
results.append(
{
"first_name": actor.first_name,
"last_name": actor.last_name,
"movies": [movie.movie.title for movie in movies]
}
)
return JsonResponse({'results': results}, status=200)
# movie의 title, running_time, 출연한 actors list 반환
class MovieView(View):
def get(self, request):
movies = Movie.objects.all()
results = []
for movie in movies:
# 중간테이블 actormovie 역참조: actormovie_set
actors = movie.actormovie_set.all()
results.append(
{
"title": movie.title,
"running_time": movie.running_time,
"actors": [actor.actor.first_name + ' ' + actor.actor.last_name for actor in actors]
}
)
return JsonResponse({'results': results}, status=200)
🧂 역참조한 내용 list로 뽑기 (ex. 배우가 출연한 영화 목록)
for actor in actors: movies = actor.actormovie_set.all() results.append( { ... # movie(ActorMovie의 인스턴스)가 참조한 movie인스턴스의 title "movies": [movie.movie.title for movie in movies] } )
shell에서 각 요소들 의미를 알아볼 수 있다.
>>> from movies.models import * >>> actors = Actor.objects.all() # Actor의 모든 인스턴스를 담은 queryset 반환 >>> actors <QuerySet [<Actor: Actor object (1)>, <Actor: Actor object (2)>, <Actor: Actor object (3)>]> >>> a2 = Actor.objects.get(id=2) >>> a2.actormovie_set.all() # id=2인 actor 인스턴스를 참조한 ActorMovie(중간테이블)의 인스턴스를 담은 queryset 반환 <QuerySet [<ActorMovie: ActorMovie object (2)>, <ActorMovie: ActorMovie object (3)>]>
Actor3
, Movie3
2개의 클래스를 만든다.ManyToManyField(참조할 클래스)
를 작성한다. 그러면 중간테이블이 자동으로 생성된다.Movie3
가 Actor3
를 참조한다.class Movie3(models.Model):
...
actors = models.ManyToManyField(Actor3)
from django.db import models
from django.db.models.base import ModelState
from django.db.models.fields import DateField, IntegerField
class Actor3(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
date_of_birth = models.DateField()
class Meta:
db_table = 'actors3'
# 참조
class Movie3(models.Model):
title = models.CharField(max_length=50)
release_date = models.DateField()
running_time = models.IntegerField()
# ManyToManyField(참조할 클래스)
actors = models.ManyToManyField(Actor3)
class Meta:
db_table = 'movies3'
import json
from django.http import JsonResponse
from django.views import View
from movies.models import Actor3, Movie3
# actor의 first_name, last_name, 출연한 movies list 반환
class Actor3View(View):
def get(self, request):
actors = Actor3.objects.all()
results = []
for actor in actors:
# actor.movie3_set.all(): actor가 Movie3를 역참조한 movie queryset 가져오기
movies = actor.movie3_set.all()
# list comprehension 대신, 리스트를 따로 만들어주는 방법
movie_list = []
for movie in movies:
movie_list.append(movie.title)
results.append(
{
'first_name': actor.first_name,
'last_name': actor.last_name,
'date_of_birth': actor.date_of_birth,
'movies': movie_list }
)
return JsonResponse({'results': results}, status=200)
# movie의 title, running_time, 출연한 actors list 반환
class Movie3View(View):
def get(self, request):
movies = Movie3.objects.all()
results = []
for movie in movies:
# movie가 참조한 actors의 모든 인스턴스의 queryset 가져오기
actors = movie.actors.all()
actor_list = []
for actor in actors:
actor_list.append(actor.first_name + ' ' + actor.last_name)
results.append(
{
'title': movie.title,
'release_date': movie.release_date,
'running_time': movie.running_time,
'actors': actor_list
}
)
return JsonResponse({'results': results}, status=200)