brunch

매거진 Django doc

You can make anything
by writing

C.S.Lewis

by 장영석 Jul 27. 2018

Django Model - ManyToManyField

Relationship fields

ManyToManyField

class ManyToManyField(to, **options)


다대다 관계다. 위치 인수가 요구된다. 모델이 관련된 클래스며, 재귀 및 지연을 포함하여 ForeignKey와 동일하게 동작한다.


관련된 객체를 필드의 RelatedManager를 사용하여 추가하고, 삭제하고, 생성할 수 있다.


Database Representation

뒹에서, Django는 다대다 관계를 표현하기 위해 중간 조인 테이블을 생성한다. 기본적으로, 테이블 이름은 다대다 필드의 이름과 포함하는 모델의 테이블 이름을 사용해서 생성된다. 일부 데이터베이스는 특정 길이의 테이블 이름을 지원하지 않는다. 이러한 테이블 이름은 자동으로 64자리로 잘리고 고유한 해시가 사용된다. author_books_9cdf4과 같은 테이블 이름을 볼 수 있을 것이다. 이 이름은 정상이다. db_table 옵션을 사용하여 조인 테이블의 이름을 수동으로 제공할 수 있다.


Arguments

ManyToManyField는 관계 함수를 제어할 수 있는 추가 인수 세트(모두 옵셔널)를 허용한다.


ManyToManyField.related_name

ForeignKey.related_name과 같다.


ManyToManyField.related_query_name

ForeignKey.related_query_name과 같다.


ManyToManyField.limit_choices_to

ForeignKey.limit_choices_to와 같다.

limit_choices_to는 through 파라미터를 사용해서 사용자 정의 중간 테이블을 지정한 ManyToManyField에는 영향이 없다.


ManyToManyField.symmetrical

오직 self에 대한 ManyToManyField 정의에 사용된다. 아래 모델을 고려해봐라.

Django가 이 모델을 처리할 때, 그 자신에 대한 ManyToManyField임을 식별한고, 결과적으로, Person    클래스에 person_set 속성을 추가하지 않는다. 대신, ManyToManyField를 대칭이라고 가정하게 된다. - 이런 거다. 내가 너의 친구라면, 너는 나의 친구다.


네가 self를 사용하는 many-to-any 관계에서 대칭을 원하지 않는다면, symmetrical을 False로 세팅해라.


ManyToManyField.through

Django는 many-to-many 관계를 관리하는 테이블을 자동으로 생성한다. 하지만, 중간 모델을 수동으로 정의하길 원한다면, through 옵션으로 사용할 중간 테이블을 나타내는 Django 모델을 지정할 수 있다.


이 옵션은 대부분의 경우 추가 데이터를 다대다 관계에 연관시킬 때 사용한다.


through를 모델에 명시적으로 정의하지 않아도, 관계를 유지하기 위해 생성된 테이블에 직접 접근하는 데 사용할 수 있는 암시적인 through 모델 클래스가 있다.


원본과 대상 모델이 다른 경우, 아래와 같이 필드가 생성된다.


id: 관계의 기본키

<containing_model>_id: ManyToManyField를 선언한 모델의 id

<other_model>_id: ManyToManyField가 가리키는 모델의 id


ManyToManyField가 선언된 모델과 가리키는 모델이 동일하다면, 아래와 같이 필드가 생성된다.


id: 관계의 기본키

from_<model>_id: 모델을 가리키는 인스턴스의 id (원본 인스턴스).

to_<model>_id: 관계가 가리키는 인스턴스의 id (타깃 모델 인스턴스).


이 클래스는 일반 모델처럼 특정 모델 인스턴스에 대하여 관련 레코드를 쿼리 하는 데 사용될 수 있다.


ManyToManyField.through_fields

오직 사용자 정의 중간 모델을 정의할 때만 사용된다. Django는 일반적으로 다대다 관계를 자동으로 설정하기 위해 사용할 중간 모델의 필드를 결정한다. 하지만 다음 모델을 고려해라.

Membership는 두 개의 Person(person필드와 inviter 필드) foreign 키가 있어, 관계를 모호하게 만들고 Django는 어느 것을 사용할지 알지 못한다. 이 경우, 위 예제처럼 through_fields를 사용하여 Django가 사용해야 하는 foreign키를 명시적으로 지정해야 한다.


through_fields는 2-tuple ('field1', 'field2')을 허용한다. field1는 ManyToManyField가 선언된 모델(이 경우는 group)에 대한 foreign키의 이름이고, field2는 대상 모델(이 경우에는 person)에 대한 foreign키의 이름이다.


다대다 관계에 참여하는 모델 중 어느 하나(또는 둘 모두)의 중간 모델에 두 개 이상의 foreign키가 있다면, through_fields를 지정해야 한다. 중간 모델이 사용되고 모델에 두 개 이상의 foreign키가 있거나 Django가 사용할 두 가지 키를 명시적으로 지정하고 싶은 경우 재귀 관계에도 적용된다.


중간 모델을 사용하는 재귀 관계는 항상 비대칭(symmetrical=False)으로 정의되어있다. 따라서, "source"와 "target" 개념이다. 이 경우는 'field1'은 관계에서 "source"로서 다뤄질 것이고 'field2'는 대상으로 다뤄질 것이다.


ManyToManyField.db_table

다대다 데이터를 저장하기 위해 생성하는 테이블의 이름이다. db_table 옵션이 제공되지 않으면, Django는 관계를 정의하는 모델의 테이블과 필드 이름을 기반으로 기본 이름을 사용한다. 


ManyToManyField.db_constraint

중간 테이블의 foreign키에 대해 데이터베이스 제약조건 생성을 제어한다. 기본값은 True이고 대부분 기본값을 원할 것이다. False로 세팅하는 것은 데이터 무결성 측면에서 매우 좋지 않을 수 있다. 아래 몇 개의 시나리오가 있다.

유효하지 않은 기존 데이터가 있다.

데이터베이스가 샤딩되어있다.

db_constraint와 through 모두 전달하면 에러가 발생한다.


ManyToManyField.swappable

ManyToManyField swappable 모델을 가리키고 있다면 마이그레이션 프레임워크의 반응을 제어한다. True 값(기본값) 일 경우 ManyToManyField가 settings.AUTH_USER_MODEL(또는 다른 swappable 모델 설정)의 값과 일치하는 모델을 가리키고 있다면 관계가 모델을 직접 사용하는 것이 아닌 설정에 대한 참조를 사용해서 마이그레이션에 저장될 것이다.


모델이 항상 스왑 된 모델을 가리켜야 하는 경우에만 False로 재정의해라. - 예를 들면, 사용자 정의 user 모델을 위해 구체적으로 설계된 profile 모델 같은 경우.


사용해도 되는지 의심스럽다면, default 설정인 True로 놔둬라.


ManyToManyField는 validotrs를 지원하지 않는다.

null은 데이터베이스 수준에서 관계를 요구할 방법이 없기 때문에 영향이 없다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari