ManyToMany 관계도에 대해 알아보자
ERD관계도에서 다대다의 관계를 가지는 테이블들을 나타낸 이미지이다.
Django에서 다대다의 관계를 정의하는 방법에 대해서 알아보자.
ForeignKey 이용하기
class A(models.Model):
class Meta:
db_table = 'A'
class B(models.Model):
class Meta:
db_table = 'B'
class Many(models.Model):
A = models.ForeignKey('A', on_delete=models.CASCADE)
B = models.ForeignKey('B', on_delete=models.CASCADE)
class Meta:
db_table = 'Many'
두 개의 클래스(테이블)을 ForeignKey를 이용하여 중계테이블을 만들어주는 모델이다.
하지만, ForeignKey를 사용하여 중계테이블을 구현하게 되면, view를 작성하기 조금 까다로워 지게 된다.
ManyToManyField
Django에서는 이런 모델을 만들때 중계테이블을 자동으로 만들어주는 필드를 제공하는데 그것이 바로 ManyToManyField이다.
(*DB에서 제공하는것이 아닌, Django에서 제공하는것이다!)
class A(models.Model):
class Meta:
db_table = 'A'
table_a = models.ManyToManyField('B')
class B(models.Model):
class Meta:
db_table = 'B'
코드의 A 클래스를 보면, table_a = models.ManyToManyField('B')가 보일것이다.
ManyToManyField를 사용하여, B 클래스와의 다대다 관계를 선언한것과 같다.
이 경우, A클래스에서 B클래스를 향해 선언되었기 때문에, A ➡️ B를 정참조, B ➡️ A를 역참조라고 한다.
!주의할점은 양쪽이 서로 ManyToManyField를 선언하면 안된다는것.
두개의 중계테이블이 만들어져, 충돌하게 될수 있다.
다른 field들과 마찬가지로 여러가지 속성을 추가할수 있는데,
자세한것은 ManyToManyField공식문서에서 확인할수 있다.
ManyToManyField 직접 사용해보기
영화배우와 영화의 관계를 ManyToMany관계로 만들어보자
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()
movies = models.ManyToManyField('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'
배우와 영화의 관계를 ManyToMany를 이용해 다대다관계로 구현한 models 코드이다.
Migrate를 한뒤, Database의 Table List를 확인해보면,
models.py에서는 구현하지 않았던 'actors_movies'라는 Table이 생성되어 있는걸 확인할수 있다.
이 테이블이 바로 ManyToManyField를 사용했을때 자동생성되는 중계테이블이다.