📌 이 포스팅에서는 테이블 간 relation을 맺을 때 중계모델에서 ForeignKey로 연결하는 것 보다 ManyToManyField를 사용했을 때 발생하는 이점에 대해서 정리하였습니다.
🔥 N:N 관계로 모델 생성하기
🔥 N:N 관계에서 데이터 삽입하기
🔥 N:N 관계에서 데이터 조회하기
✔️ ForeignKey를 사용한 단순 직관 모델로 N:N 관계를 형성하면 두 테이블을 연결지어 줄 중계 모델이 필요하다.
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 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") class Meta: db_table = "actor_movies"
✔️ ManyToManyField를 사용하면, 중계모델이 필요없다. 알아서 Django에서 만들어주기 때문에 간편하다.
✔️ 또한 N:N 관계일 때는 ManyToManyField를 사용하는 것이 더 직관적으로 알아보기 쉽다.
✔️ 뿐만아니라 여러 relation이 함께 존재할 때, through, through_field 옵션을 가지고 제어할 수 있다.
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 Movie(models.Model): title = models.CharField(max_length=45) release_date = models.DateField() running_time = models.IntegerField() actor = models.ManyToManyField("Actor") class Meta: db_table = "movies"
✔️ ForeignKey로 중계모델을 생성한 뒤, 이를 통해 다른 테이블을 참조했기 때문에 Actor과, Movie에 데이터를 생성 후, 중계모델(ActorMovie)에 데이터를 또 다시 삽입하여 연결해주어야 한다.
# python manage.py shell >>> from movies.models import * >>> Actor.objects.create(first_name="정재", last_name="이", date_of_birth="2021-01-02") >>> Actor.objects.create(first_name="정민", last_name="황", date_of_birth="2020-11-08") >>> Movie.objects.create(title = "다만 악에서 구하소서",release_date = "2021-11-11", running_time=129) >>> a1 = Actor.objects.get(id=1) >>> a2 = Actor.objects.get(id=2) >>> m1 = Movie.objects.get(id=1) >>> ActorMovie.objects.create(actor=a1, movie=m1) >>> ActorMovie.objects.create(actor=a2, movie=m1)
✔️ 이에 반해 ManyToManyField로 중계모델이 없이 N:N 관계를 형성했을 때는 add를 통해 바로 삽입이 가능하고, 한번에 여러 객체를 담을 수 있기 때문에 훨씬 편리하다.
# python manage.py shell >>> from movies.models import * >>> a1 = Actor(first_name="정재", last_name="이", date_of_birth="2021-01-02") >>> a1.save() >>> a2 = Actor(first_name="정민", last_name="황", date_of_birth="2020-11-08") >>> a2.save() >>> m1 = Movie(title = "다만 악에서 구하소서",release_date = "2021-11-11", running_time=129) >>> m1.save() >>> m1.actor.add(a1,a2) # 👈 ManyToMany 필드 데이터 삽입
# python manage.py shell >>> from movies.models import * >>> a1 = Actor.objects.get(id=1) >>> a1.actorMovie_set.get().movie.name # 👈 "다만 악에서 구하소서"
# python manage.py shell >>> from movies.models import * >>> a1 = Actor.objects.get(id=1) >>> a1.movie_set.get().name # 👈 "다만 악에서 구하소서"