Django(4):ManyToMany relationship

signet·2021년 1월 31일
0

Django로 데이터베이스를 다루는 일에 있어서, 다대다 관계의 경우, 중계 테이블을 만들어주는 방법이 있고, 한편으로 Django에서 제공하는 방법을 이용할 수도 있다. 각각에 따라 모델 형식은 물론 데이터를 다루는 방법이 달라지기 때문에, 이를 가능한 만큼 정리해보고자 한다.

1. 중계 테이블을 만드는 경우

중계 테이블을 작성하고, 그곳에 다대다 관계로 연결하고자 하는 두 테이블의 PK를 FK로 연결하는 방법이다. 이 방법은 중계 테이블이 실재로 존재하기 때문에, 다른 값을 생성, 수정하는 방식과 동일한 방법으로 값에 직접 접근하여 수정, 추가할 수 있다는 장점이 있다. 하지만 값을 불러올 때, 중계 테이블에서 다시 참조를 하도록 설정해주어야 할 필요가 있어 하나의 로직이 더 필요하다는 단점이 있다.

2. ManyToManyField를 선언하는 경우

이 경우는 Django에서 제공하는 방법을 사용하는 것으로,

attributename = models.ManyToManyField('classname', through='name')

의 형식으로 모델을 구성한다. 이때, 필드는 양 테이블 중 어디에 선언해도 상관은 없지만, 좀 더 주가 되는 테이블에 선언하는 것이 일반적이다. 이렇게 하면, 실질적으로 중계 테이블이 생성되는 것은 아니지만, 논리적으로 생성되어 데이터베이스에서도 확인은 가능하다. 하지만 중계 테이블의 값을 직접 추가하거나 수정하지는 못한다. 하지만 중계테이블에서 다시 참조할 필요 없이 한번 선언한 변수에서 경로를 추적할 수 있기 때문에 이점이 있다. 이를 생성하고 추가하기 위해서는 다음과 같은 방법들이 있다.

variable = Class(attribute)
variable2 = Class2(attribute)
variabe1.attributename.add(variable2)

혹은

 instance.attributename.set(Class2.objects.filter(name='')

의 방법이 있다. 이는 생성하는 방법이다.

(추가사항): 값을 불러올 때도 직접 불러오지 못한다. 이때도 다른 방법이 필요한데

instance.attributename.values() or all()

으로 불러올 수 있다. 하지만 이렇게 하면 쿼리셋으로 값을 반환하므로, 리스트 형식으로 다시 변환할 필요가 있는데, 이때 원하는 attribute속성은 물론 id와 같이 다른 값들도 한꺼번에 불러오게 되어 번거롭다. 이를 처리할 수 있는 방법을 추가로 공부해보고자 한다.

0개의 댓글