한국어로 옮기기 어색한 단어들은 영문으로 혹은 해석이 애매한 구절은 직역한 그대로 사용 하였습니다.
다대다 관계
Many-to-many 관계를 정의하기 위해서 ManyToManyField
를 사용해야한다. 당신은 다른 Field
type을 사용했던 것처럼 사용할 수 있다:당신의 모델의 클래스 속성으로 포함하는 방법으로 사용가능하다
ManyToManyField
는 positional argument를 요구한다:모델과 관련된 클래스
예를들면, 만약 Pizza
가 여러개의 Topping
객체를 가지고 있다면,- 즉, 1개의 Topping
은 여러개의 피자에 올 수 있고, 각각의 피자는 여러개의 Topping
을 가질 수 있다- 아래와 같이 표현할 수 있다.
xxxxxxxxxx
from django.db import models
class Topping(models.Model):
# ...
pass
class Pizza(moels.Model):
# ...
toppngs = models.ManyToManyField(Topping)
외래키와 마찬가지로, 당신은 재귀적인 관계와, (다대다 관계가 있는 객체), 모델에 정의되지 않은 관계를 생성할 수 있다.
ManyToManyField
(위의 예에서 토핑)의 이름은 관련 모델 개체 집합을 설명하는 복수형이어야하지만 필수는 아니다
어떤 모델이 ManyToManyField
를 가지는지는 문제가 아니다, 대신에 당신은 두개의 모델 모두가 아닌 1개에만 두어야 한다.
대개의 경우 ManyToManyField
인스턴스는 폼에서 수정될 객체 내로 가야한다.
위의 예에서 Pizza
안의 toppings
가 있는데, 피자가 토핑을 가지고 있는 것이 토핑이 여러개의 피자위에 있다 보다 더 자연스럽기 때문이다. 위의 설정 방식에서 피자 양식을 사용하면 사용자가 토핑을 선택할 수 있다.
See also
다대다 관계 모델 예제 에서 풀 예제를 보자
ManyToManyField
필드는 추가적인 argument 를 수락해야한다 이 내용은 모델 필드 레퍼런스 에 설명 되어있다. 이러한 옵션들은 어떻게 관계가 동작해야하는지 정의 하는 것을 도와준다.;모든 것은 선택적으로 사용하면 된다.
내 마음대로 해설
처음 개발을 시작했을 때, 관계 중에서 제일 이해가지 않았던게 다대다 였다. 흔히 생각할 때, 블로그에서 글과 댓글의 관계는 일대다, 글과 태그의 관계는 다대다의 관계로 본다.
다대다의 가장 큰 특징은 일대다와 비교해보았을 때, 일대다는 어느 한쪽에 종속되는 개념이다 이에 반해서 다대다는 어느 한쪽에만 종속되지 않는다.
위 예제를 보았을 때, Pizza 는 여러 개의 Topping을 가질 수 있고, Topping들도 여러 개의 Pizza에 속할 수 있다.
ManyToManyField
는 관계가 있는 모델 중 1개에 속하면 된다.
x
# 이런 형태 - 1
class Pizza(models.Model):
name = models.CharField(max_length=100)
toppings = models.ManyToManyField("Topping")
class Meta:
db_table = "pizza"
class Topping(models.Model):
name = models.CharField(max_length=100)
class Meta:
db_table = "topping"
# 혹은 이런 형태로 - 2
class Pizza(models.Model):
name = models.CharField(max_length=100)
class Meta:
db_table = "pizza"
class Topping(models.Model):
name = models.CharField(max_length=100)
pizzas = models.ManyToManyField("Pizza")
class Meta:
db_table = "topping"
1의 형태는 아래와 같은 쿼리 문으로 테이블이 생성된다.
x
BEGIN;
--
-- Create model Topping
--
CREATE TABLE "topping" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(100) NOT NULL);
--
-- Create model Pizza
--
CREATE TABLE "pizza" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(100) NOT NULL);
CREATE TABLE "pizza_toppings" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "pizza_id" integer NOT NULL REFERENCES "pizza" ("id") DEFERRABLE INITIALLY DEFERRED, "topping_id" integer NOT NULL REFERENCES "topping" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE UNIQUE INDEX "pizza_toppings_pizza_id_topping_id_8f3bc27a_uniq" ON "pizza_toppings" ("pizza_id", "topping_id");
CREATE INDEX "pizza_toppings_pizza_id_1d874c42" ON "pizza_toppings" ("pizza_id");
CREATE INDEX "pizza_toppings_topping_id_415abd80" ON "pizza_toppings" ("topping_id");
COMMIT;
테이블을 총 3개 만드는 것을 볼 수 있다. topping과 pizza 각각 1개 피자와 토핑의 관계를 나타내주는 테이블인 pizza_toppings 이다.
2의 형태는 1과 반대로 topping_pizzsa 라는 테이블이 추가로 만들어 질 것이다.
xxxxxxxxxx
BEGIN;
--
-- Create model Pizza
--
CREATE TABLE "pizza" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(100) NOT NULL);
--
-- Create model Topping
--
CREATE TABLE "topping" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(100) NOT NULL);
CREATE TABLE "topping_pizzas" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "topping_id" integer NOT NULL REFERENCES "topping" ("id") DEFERRABLE INITIALLY DEFERRED, "pizza_id" integer NOT NULL REFERENCES "pizza" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE UNIQUE INDEX "topping_pizzas_topping_id_pizza_id_180d94d2_uniq" ON "topping_pizzas" ("topping_id", "pizza_id");
CREATE INDEX "topping_pizzas_topping_id_e478b175" ON "topping_pizzas" ("topping_id");
CREATE INDEX "topping_pizzas_pizza_id_02e8ae65" ON "topping_pizzas" ("pizza_id");
COMMIT;
문서 상에서 말한 대개의 경우 ManyToManyField 인스턴스는 폼에서 수정될 객체 내로 가야한다.
에 따르면 2번 보다는 1번이 더 자연스러울 듯하다.
두번째 문장으로,
ManyToManyField (위의 예에서 토핑)의 이름은 관련 모델 개체 집합을 설명하는 복수형이어야하지만 필수는 아니다
는 개인적으로 이 말은 왠만하면 복수형이 좋은 것
세번째 문장으로,
대개의 경우 ManyToManyField 인스턴스는 폼에서 수정될 객체 내로 가야한다.
는 admin 기준으로 보면 아래와 같은 설명일 것으로 추측한다.
이렇게 토핑에 피자가 속한 것 처럼 표현하기 보단,
피자에 어떤 토핑이 있는지 폼을 통해서 수정하는게 훨씬 더 자연스럽다 물론 반대로 표현한다고 해서 틀린 것은 아니고, 본인이 필요한 방향에 따라서 사용하면 될 것 같다.
'개발 > 장고' 카테고리의 다른 글
[Django] 다대다 관계의 모델을 직접 활용해 보자 (0) | 2021.01.30 |
---|---|
[Django] 다대다 관계에서 중개 모델의 제한 사항 (0) | 2021.01.30 |
[해설과 함께 읽는 Django 문서] Models - 다 대 일 관계 (0) | 2021.01.27 |
[해설과 함께 읽는 Django 문서] Models - Verbose Field 이름 (0) | 2021.01.24 |
[해설과 함께 읽는 Django 문서] Models - Automatic primary key 필드 (0) | 2021.01.24 |