[django] C.R.U.D 2 (2) 배우와 영화 (feat. manytomanyfield)

django - C.R.U.D 2 2편

배우 테이블과 영화 테이블을 만들어서 N:N 관계의 테이블과 해당 앱을 완성시켜 보자.


기존에는 ForeignKey를 사용해서 테이블 관계를 형성했는데, 이번에도 ForeignKey를 우선 먼저 사용해봤다.

#models.py
from django.db import models

# Create your models here.
class Actor(models.Model):
    first_name 	  = models.CharField(max_length=45)
    last_name     = models.CharField(max_length=45)
    date_of_birth = models.DateField()

    class Meta:
        db_table = 'actors'

class Movie(models.Model):
    title        = models.CharField(max_length=45)
    release_date = models.DateField()
    running_time = models.IntegerField()

    class Meta:
        db_table = 'movies' 


class ActMovie(models.Model):
    actor = models.ForeignKey('Actor',on_delete=models.CASCADE)
    movie = models.ForeignKey('Movie',on_delete=models.CASCADE)

    class Meta:
        db_table = 'acts_movies'

ForeignKey를 만들면 결국 중간테이블 ActMovie를 만들어야 한다.
그래야 각 column 별로 ForeignKey를 생성할 수 있기 때문.

하지만 manytomanyfield는 다르다.
django documentation 의 예시를 통해서도 보듯이,
1) 중간테이블을 별도로 만들어줄 필요가 없으며
(manytomanyfield는 참조를 더 많이 할 것 같은 클래스에 넣으면 됨)
2) 바로 N:N 관계의 테이블에 가서 데이터를 갖고 올 수 있다.

그래서 위 테이블을 다시 manytomanyfield로 바꾸면 아래와 같다. 그리고 manytomanyfield 를 담는 변수는 복수형이다.

#models.py
class Actor(models.Model):
    first_name    = models.CharField(max_length=45)
    last_name  	  = models.CharField(max_length=45)
    date_of_birth = models.DateField()
 	#ActorMovie는 중간테이블 
    movies 		  = models.ManyToManyField('Movie', through 'ActorMovie') 

    class Meta:
        db_table = 'actors'

class Movie(models.Model):
    title = models.CharField(max_length=45)
    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 = 'actormovie'

마지막에 중간테이블을 작성했는데, 실제로는 중간테이블에도 column들을 추가할 가능성이 크기 때문에 필요하다.
(더 자세한 테이블 작성 가능)

views.py는 아래와 같다.

import json

from django.http  import JsonResponse
from django.views import View

from .models import Actor, Movie

#배우의 이름, 성, 그리고 출연한 영화 제목 목록
class ActorView(View):
    def get(self,request):
        result = [{
            'first_name' : actor.first_name,
            'last_name'  : actor.last_name,
            'movie_lst'  : [{
                'title'  : movie.title,
            } for movie in actor.movies.all()]
        } for actor in Actor.objects.all()]

        return JsonResponse({'result':result},status=201)   
     
     
#영화의 제목, 상영시간, 출연한 배우 목록 (last_name)
#last_name -> full name으로 살짝 바꿈 
class MovieView(View):
    def get(self,request):
        result = [{
            'title'        : movie.title,
            'running_time' : movie.running_time,
            'actor_lst'    : [{
                'actor' : actor.last_name + actor.first_name
            } for actor in movie.actors_set.all()]
        } for movie in Movie.objects.all()]
    
        return JsonResponse({'result':result}, status=201)

좋은 웹페이지 즐겨찾기