두 가지의 방법이 있다 ForeignKey
를 사용하여 중간테이블을 만드는 법과 ManyToManyField
를 사용하여 중간테이블을 사용하지 않고 코드를 작성할 수 있어 코드의 가독성이 좋아지는 장점이 있다.
하지만 django
에서만 제공해주는 특성이기에 ManyToManyField
없이도 데이터를 가지고 올 수 있어야한다.
위 ERD 를 보고 두가지의 models.py를 작성할 수 있다.
1) ForeignKey(중간테이블)을 활용한 코드
# ForeignKey(중간테이블)을 활용한 코드
from django.db import models
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 Actor_Movie(models.Model):
actor = models.ForeignKey('Actor', on_delete = models.CASCADE)
movie = models.ForeignKey('Movie', on_delete = models.CASCADE)
class Meta:
db_table = 'actors_movies'
class Movie(models.Model):
title = models.CharField(max_length=45)
release_date = models.DateField()
running_time = models.IntegerField()
class Meta:
db_table = 'movies'
2) ManyToManyField를 활용한 코드
# ManyToManyField를 활용한 코드
class Actor(models.Model):
first_name = models.CharField(max_length=45)
last_name = models.CharField(max_length=45)
date_of_birth = models.DateField()
movies = models.ManyToManyField('Movie', through=Actor_Movie)
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'
위 코드를 보면 2)번 코드의 경우 Actor_Movie라는 class를 따로 만들어 줄 필요없이 연결해줄 class에 ManyToManyField를 활용하여 through 속성을 주면 중간테이블을 생성해준다.
1) ForeignKey(중간테이블)을 활용한 코드
# ForeignKey(중간테이블)을 활용한 코드
class ActorsView(View):
def get(self, request):
actors = Actor.objects.all()
result = []
for actor in actors:
movie_list = []
for actor_movie in actor.actor_movie_set.all():
movie_list.append({
"title" : actor_movie.movie.title,
"release_date" : actor_movie.movie.release_date,
"running_time" : actor_movie.movie.running_time,
})
result.append({
"first_name" : actor.first_name,
"last_name" : actor.last_name,
"date_of_birth" : actor.date_of_birth,
"movie" : movie_list,
})
return JsonResponse({'result':result}, status=200)
class MoviesView(View):
def get(self, request):
movies = Movie.objects.all()
result = []
for movie in movies:
actor_list = []
for actor_movie in movie.actor_movie_set.all():
actor_list.append({
"first_name" : actor_movie.actor.first_name,
"last_name" : actor_movie.actor.last_name,
"date_of_birth" : actor_movis.actor.date_of_birth,
})
result.append({
"title" : movie.title,
"release_date" : movie.release_date,
"running_time" : movie.running_time,
"actor" : actor_list,
})
return JsonResponse({'result':result}, status=200)
2) ManyToManyField를 활용한 코드
class ActorsView(View):
def get(self, request):
actors = Actor.objects.all()
result = []
for actor in actors:
movie_list = []
for movie in actor.movies.all():
movie_list.append({
"title" : movie.title,
"release_date" : movie.release_date,
"running_time" : movie.running_time,
})
result.append({
"first_name" : actor.first_name,
"last_name" : actor.last_name,
"date_of_birth" : actor.date_of_birth,
"movie" : movie_list,
})
return JsonResponse({'result':result}, status=200)
class MoviesView(View):
def get(self, request):
movies = Movie.objects.all()
result = []
for movie in movies:
actor_list = []
for actor in movie.actors.all():
actor_list.append({
"first_name" : actor.first_name,
"last_name" : actor.last_name,
"date_of_birth" : actor.date_of_birth,
})
result.append({
"title" : movie.title,
"release_date" : movie.release_date,
"running_time" : movie.running_time,
"actor" : actor_list,
})
return JsonResponse({'result':result}, status=200)
위 코드를 자세하게 보면 기존 중간테이블을 역참조해주던 actor_movie_set
을 사용하지 않고 바로 연결 할 테이블로 작성해주고 중간테이블의 actor_movie
를 사용하지 않아 코드가 더욱 가독성이 높아진 걸 확인할 수 있다.
하지만 ManyToMany 테이블
을 쓰던 안쓰던 결국 중간테이블
을 통하여 데이터를 가져와야하는것은 같기 때문에 django 이외에 다른 프레임워크를 사용할 수 도 있기에 사용하는 것을 지양해야겠다.