[Django] ManyToManyField(다대다)와 Foreign Key(외래키)

mean_g·2022년 7월 6일
0

[ Python & Django ]

목록 보기
3/10

1. Foreign Key(외래키)란?

  • 외래키(Foreign Key)란 테이블의 필드(attribute) 중 다른 테이블의 행(row)를 식별할 수 있는 키다.
    일반적으로 외래키 값을 가지고 있는 테이블을 부모 테이블, 외래키가 포함된 테이블을 자식 테이블이라고 한다.

  • 데이터베이스에 테이블을 만들 때 효율적으로 테이블을 만들 수 있게 해준다. 쉽게 생각하면 테이블과 테이블을 연결해 준다고 생각하면 될 거 같다.

2. Many to Many(다대다)란?

  • 별도로 중간 테이블을 설정해 주지 않아도 자동으로 중간 테이블을 설정해 준다.
class Movie(models.Model):
    title = models.CharField(max_length=50)
    release_date = models.DateField()
    running_time = models.CharField(max_length=50)

    class Meta:
        db_table = 'movies'

class Actor(models.Model):
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=50)
    date_of_birth = models.DateField()
    movie = models.ManyToManyField(Movie, through='ActorMovie')

    class Meta:
        db_table = 'actors'
  • 위 코드처럼 두 개의 테이블을 생성하고 ManyToMany Field를 사용해서 Actor 테이블이 Movie 테이블을 참조하도록 만들었다.
    여기서 중간 테이블을 따로 만들지 않았지만, 자동적으로 중간 테이블이 생기며 DB를 확인해 보면 ManyToMany Field로 엮인 두 테이블 이름에 _을 넣어준 새로운 테이블이 생겨난다.

  • through 옵션을 사용하지 않는다면 중간 테이블에 직접 접근해서 객체로 사용할 수는 없다.
    어떤 객체를 생성하고 해당 객체를 통해 중간 테이블에 접근하여 객체를 사용해야 해서 loss 발생하게 된다.
    ManyToMany Field 사용 중에도 중간 테이블을 직접 설정해 주고 through 옵션으로 중간 테이블임을 인식시켜줘야 한다.

  • 여기서는 Movie에서 Actor를 참조할 수 있기 때문에, 거꾸로 Actor에서 Movie를 가져오기 위해 actor.movies.all() 을 사용하면 ActorMovie와 연결되지 않았으므로 AttributeError 가 뜨고 직접적으로 데이터를 가져올 수는 없다.

_set 붙혀주기 :

actor1.movie_set.all()
<QuerySet [<movie: actor>]>

→ related_name : _set 대신 사용이 가능하다.

class Movie(models.Model):
		...
		actors = models.ManyToManyField('Actor', related_name='movies')

related_name은 참조되는 테이블이 참조하는 테이블의 데이터를 가져오기 위해 사용하는 이름을 정의한다.

actor1.movies.all()
<QuerySet [<movie: actor>]>

이경우 정상적으로 출력되는 걸 확인할 수 있다.

3. ManyToManyField의 이점은 무엇일까?

1) 중간 테이블을 직접 만들어주지 않아도 된다.
2) 중간 테이블을 거치지 않고 언제든지 데이터를 쉽게 추가하고 가져올 수 있다.

profile
Backend Dev

0개의 댓글