앞의 Owners-Cats로 일대다 관계에 대해 알아보았고, 이제는 다대다 관계에서 어떻게 해보는지 알아보려고 테이블을 만들어봤다.
영화-영화배우 관계는 다대다 관계이다.
위의 테이블을 간단하게 만들어 다대다 관계에서 어떻게 정보를 GET 해오는지 알아보자.
앞에서 항상 하던대로 가상환경 설정하고 기본 세팅까지 완료하였다.
--
위와 같이 배우, 영화, 그리고 배우-영화 중간테이블을 생성하였다.
--
POST 기능을 구현하고자 했으나 구현에 애를 먹어 일단 급한대로 쉘로 작성을 하였다.
쉘을 선언해서 모델을 임포트하려고 했는데 계속 에러가 뜨길래 봤더니 디렉토리에 잘못 가있었다...
다음부턴 디렉토리를 한번 더 생성하고 가야겠다.
자 이제 위 그림을 보면서 생각을 해보자.
닉과 노라의 인피니트 플레이리스트
에는 캣 데닝스
와 마이클 세라
가 출연했다.
그리고 캣 데닝스
는 닉과 노라의 인피니트 플레이리스트
와 그녀의 팔에 사랑을 새겨줘
에 출연했다.
만약 내가 캣 데닝스
의 이름과 생일을 출력하면서, 출연한 영화들도 같이 뽑고 싶으면 어떻게 불러와야 할까?
FK가 없으므로 불러올 수가 없다.
그러면?
중간 테이블을 이용하면 된다.
# movies/views.py
import json
from django.shortcuts import render
from django.http import JsonResponse
from django.views import View
from movies.models import Actor, Movie, MovieActor
class ActorsView(View):
def get(self, request):
movies_actors = MovieActor.objects.all()
results = []
for movie_actor in movies_actors:
results.append(
{
'Actor\'s Name' : movie_actor.actor.name ,
'Actor\'s Date of Birth' : movie_actor.actor.date_of_birth ,
'Filmography' : movie_actor.movie.title ,
}
)
return JsonResponse({'Search Result' : results}, status=200)
class MoviesView(View):
def get(self, request):
movies_actors = MovieActor.objects.all()
results = []
for movie_actor in movies_actors:
results.append(
{
'Movie Title' : movie_actor.movie.title ,
'Running Time' : movie_actor.movie.running_time,
'Cast' : movie_actor.actor.name ,
}
)
return JsonResponse({'Search Result' : results}, status=200)
위 코드를 보면, 애초에 중간테이블 자체에 영화와 배우의 FK가 있으므로, 해당 테이블을 거치면서 정보를 불러오면 되는 것이다.
# movies/urls.py
from django.urls import path
from movies.views import ActorsView, MoviesView
urlpatterns = [
path('actors', ActorsView.as_view()),
path('movies', MoviesView.as_view())
]
# urls.py
from django.urls import path, include
urlpatterns = [
path('cinemas/', include('movies.urls'))
]
이제 httpie를 이용하여 Actor의 정보를 호출해볼 것이다.
http -v GET 127.0.0.1:8000/cinemas/actors
터미널에 위와 같이 입력
굳이 Actor 테이블부터 시작을 하지 않더라도 모든 정보를 중간 테이블을 이용하여 불러올 수 있다.
이번엔 이용하여 Movies의 정보를 호출해볼 것이다.
http -v GET 127.0.0.1:8000/cinemas/movies
역시나 잘 불러와진다!
위 방법은 중간 테이블의 테이블을 model로 선언했지만, ManyToMany 필드를 Actor 또는 Movie에 선언한다면 중간 테이블을 만들지 않아도 된다고 한다.
(정확히 말하면 mySQL에서 알아서 생성을 한다고 한다.)
이 방법을 이용한다면 어떤 차이가 있는지를 알아보고 싶긴 한데.. 지금 배운것도 적용하기 어려워 할 수 있을까 싶다.
두 방법의 확실한 차이를 안다면 적재적소에 적용할 수 있지 않을까 싶다.