프레임워크+라이브러리/Django
[MySQL, Django]ManyToManyField를 쓰는 이유
moonionn
2021. 3. 30. 20:40
👇 전반적인 예시 모델
class User(models.Model):
email = models.EmailField(max_length=100)
password = models.CharField(max_length=500)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'users'
class Coupon(models.Model):
name = models.CharField(max_length=100)
discount_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
discount_percent = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'coupons'
class CouponUser(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
coupon = models.ForeignKey(Coupon, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'coupon_users'
👇유저와 쿠폰 하나씩 생성
>>> usr = User(email='hello@test.com', password=1234)
>>> usr.save()
>>> cp = Coupon(name='신학기 할인', discount_percent=10)
>>> cp.save()
1. Foriegn Key로만 관계를 설정했을 때
연결되어 있는 타 테이블과의 작업을 하려면
중간 테이블을 거치는 방법 밖에 뜨지 않습니다.
따라서 값을 넣어주려 할 때도 연결 테이블을 통해 저장해줘야 합니다.
>>> connect = CouponUser(user=usr, coupon=cp)
>>> connect.save()
값을 불러올 때도 중간 테이블의 값만 불러올 수 있습니다.
>>> cp.couponuser_set.values()
<QuerySet [{'id': 6, 'user_id': 3, 'coupon_id': 5, 'created_at': datetime.datetime(2021, 3, 30, 19, 56, 20, 882987)}]>
연결되어 있는 저너머의 테이블 정보를 보고 싶으면
중간 테이블을 한 번 거쳐야 합니다.
>>> for issue in cp.couponuser_set.all():
... print(issue.user.email)
hello@test.com
>>> for my_coupon in usr.couponuser_set.all():
... print(my_coupon.coupon.name)
신학기 할인
2. ManyToManyField를 썼을때
user나 coupon object에서 바로 연결값을 추가할 수 있습니다.
>>> usr.coupon_set.add(cp)
(위와는 반대의 경우)
>>> cp.user.add(usr)
따라서 연결된 테이블 정보를 가져오는 과정도
1번(FK만 지정했을때) 보다 훨씬 간단합니다.
>>> for issue in cp.user.all():
... print(issue.email)
hello@test.com
>>> for my_coupon in usr.coupon_set.all():
... print(my_coupon.name)
신학기 할인