Django C.R.U.D - M2M 관계

jinatra·2021년 8월 20일
1

Django

목록 보기
3/9
post-thumbnail

Django C.R.U.D - M2M 관계


Many To Many 관계

앞의 Owners-Cats로 일대다 관계에 대해 알아보았고, 이제는 다대다 관계에서 어떻게 해보는지 알아보려고 테이블을 만들어봤다.


AQuery 이용하여 모델 설정

영화-영화배우 관계는 다대다 관계이다.
위의 테이블을 간단하게 만들어 다대다 관계에서 어떻게 정보를 GET 해오는지 알아보자.


기초세팅

앞에서 항상 하던대로 가상환경 설정하고 기본 세팅까지 완료하였다.

--

models.py 입력

위와 같이 배우, 영화, 그리고 배우-영화 중간테이블을 생성하였다.

--

데이터 입력

POST 기능을 구현하고자 했으나 구현에 애를 먹어 일단 급한대로 쉘로 작성을 하였다.


과정 중의 실수

쉘을 선언해서 모델을 임포트하려고 했는데 계속 에러가 뜨길래 봤더니 디렉토리에 잘못 가있었다...
다음부턴 디렉토리를 한번 더 생성하고 가야겠다.


Views.py 작성

자 이제 위 그림을 보면서 생각을 해보자.
닉과 노라의 인피니트 플레이리스트에는 캣 데닝스마이클 세라가 출연했다.
그리고 캣 데닝스닉과 노라의 인피니트 플레이리스트그녀의 팔에 사랑을 새겨줘에 출연했다.
만약 내가 캣 데닝스의 이름과 생일을 출력하면서, 출연한 영화들도 같이 뽑고 싶으면 어떻게 불러와야 할까?
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가 있으므로, 해당 테이블을 거치면서 정보를 불러오면 되는 것이다.


urls.py 작성

movies/urls.py 작성

# 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())
]

main urls.py 작성

# urls.py
from django.urls import path, include

urlpatterns = [
    path('cinemas/', include('movies.urls'))
]

Actor 정보 호출

이제 httpie를 이용하여 Actor의 정보를 호출해볼 것이다.

http -v GET 127.0.0.1:8000/cinemas/actors

터미널에 위와 같이 입력

굳이 Actor 테이블부터 시작을 하지 않더라도 모든 정보를 중간 테이블을 이용하여 불러올 수 있다.


Movie 정보 호출

이번엔 이용하여 Movies의 정보를 호출해볼 것이다.

http -v GET 127.0.0.1:8000/cinemas/movies

역시나 잘 불러와진다!





Take Away

ManyToMany Field 활용

위 방법은 중간 테이블의 테이블을 model로 선언했지만, ManyToMany 필드를 Actor 또는 Movie에 선언한다면 중간 테이블을 만들지 않아도 된다고 한다.
(정확히 말하면 mySQL에서 알아서 생성을 한다고 한다.)

이 방법을 이용한다면 어떤 차이가 있는지를 알아보고 싶긴 한데.. 지금 배운것도 적용하기 어려워 할 수 있을까 싶다.

두 방법의 확실한 차이를 안다면 적재적소에 적용할 수 있지 않을까 싶다.


profile
으악

0개의 댓글