TIL45. Django : Many To Many Field 사용의 장점

ID짱재·2021년 10월 19일
0

Django

목록 보기
35/43
post-thumbnail

📌 이 포스팅에서는 테이블 간 relation을 맺을 때 중계모델에서 ForeignKey로 연결하는 것 보다 ManyToManyField를 사용했을 때 발생하는 이점에 대해서 정리하였습니다.



🌈 Many To Many Field 사용의 장점

🔥 N:N 관계로 모델 생성하기

🔥 N:N 관계에서 데이터 삽입하기

🔥 N:N 관계에서 데이터 조회하기



1. N:N 관계로 모델 생성하기

🤔 ForeignKey로 사용하여 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로 사용하여 N:N 모델 생성하기

✔️ 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"


2. N:N 관계에서 데이터 삽입하기

🤔 데이터 삽입할 때는 어떤 차이가 있을까?

✔️ 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 필드 데이터 삽입 


3. N:N 관계에서 데이터 조회하기

🤔 ForeignKey로 관계를 형성했을 때는 중계모델을 거쳐야 한다.

# python manage.py shell
>>> from movies.models import *
>>> a1 = Actor.objects.get(id=1)
>>> a1.actorMovie_set.get().movie.name # 👈 "다만 악에서 구하소서"

🤔 ManyToMany 필드를 사용했을 때는 정참조 또는 역참조로 바로 접근이 가능하다.

# python manage.py shell
>>> from movies.models import *
>>> a1 = Actor.objects.get(id=1)
>>> a1.movie_set.get().name # 👈 "다만 악에서 구하소서"
profile
Keep Going, Keep Coding!

0개의 댓글