[Django] ManyToManyField
ManyToManyField
django에서 다대다 관계는 ManyToManyField
로 표현할 수 있습니다.
간단하게 고객과 아이스크림의 관계를 ManyToManyField
로 표현 해보겠습니다.
ManyToManyField 예제
class Customer(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Icecream(models.Model):
name = models.CharField(max_length=20)
customer = models.ManyToManyField(Customer, related_name="favorite_icecream")
def __str__(self):
return self.name
Icecream 모델의 customer필드를 ManyToManyField
지정했습니다. Customer 모델과 Icecream 모델 둘 중 어느곳에나 지정 할 수 있지만 Customer모델은 다른 모델들과도 엮일 가능성이 높으므로 Icecream모델에 ManyToManyField
넣어줬습니다.
위와같이 모델을 설계하고 DB migration을 해주면!

자동으로 customer와 icecream의 id값을 외래키로 갖는 icecream_customer 테이블이 생성됩니다.
각 모델에서 상대 모델에 접근하는 방법은 다음과 같습니다.
icecream = Icecream.objects.get(name='구구콘')
customer = Customer.objects.all()
icecream.customer.set(customer)
# or
icecream.customer.add(customer[0])
# customer in icecream
Icecream.objects.get(name='누가바').customer.all()
# icecream in customer if related_name
Customer.objects.get(name='James').favorite_icecream.all()
through model
through model은 자동으로 만들어지는 icecream_customer을 직접 생성해줄 수 있습니다.
기존 필드에 through로 모델명을 추가해 주면 됩니다.
class Icecream(models.Model):
name = models.CharField(max_length=20)
customer = models.ManyToManyField(Customer, through='IcecreamCustomer', related_name="favorite_icecream")
다음과 같이 원하는대로 모델을 설계할 수 있습니다.
class IcecreamCustomer(models.Model):
icecream = models.ForeignKey(Customer, on_delete=models.CASCADE)
customer = models.ForeignKey(Icecream, on_delete=models.CASCADE)
class Meta:
db_table = "icecream_customer"
unique_together = ('icecream', 'customer')
딱 태그만 추가하고 싶을때 (taggit)
https://github.com/jazzband/django-taggit
GitHub - jazzband/django-taggit: Simple tagging for django
Simple tagging for django. Contribute to jazzband/django-taggit development by creating an account on GitHub.
github.com
ManyToMany필드를 만들기 귀찮을때 쓰기 좋을거 같습니다. 필드에 넣어주기만 하면 자동으로 ManyToMany필드와 같은 기능을 쓸 수 있게 생성이 되는 모듈인거 같습니다.
import후 migrate를 해주면 두개의 taggit_tag, taggit_taggeditem 테이블이 생기는데 taggit_tag에는 직접적인 태그들이 저장되고, taggit_taggeditem에는 tag와 tag가 달려있는 model과 연결해주고 있습니다. 여러 모델에서 간단한 태그들이 필요할때 좋을거 같습니다.