상세 컨텐츠

본문 제목

[MySQL, Django]ManyToManyField를 쓰는 이유

프레임워크+라이브러리/Django

by 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)
신학기 할인

관련글 더보기

댓글 영역