TIL 20. Reverse relations & Related name

요니·2021년 11월 14일
1

Python

목록 보기
6/7
post-thumbnail

정참조와 역참조 객체 호출하기

데이터베이스에서 두 테이블이 참조 관계에 있는 경우를 생각해봅시다.
예를 들어, Product 테이블과 상품의 후기인 Comment 테이블이 있습니다. 두 테이블은 1:N 관계에 있다고 했을 때, Comment 의 객체가 Product 의 객체를 참조하고 있습니다.

class Product(models.Model) : 
      subcategory_id = models.ForeignKey('Subcategory', on_delete=models.CASCADE)
      name           = models.CharField(max_length=500)
      price          = models.DecimalField(max_digits=7, decimal_places=2)

class Comment(TimeStampModel):
    product_id = models.ForeignKey('products.Product', on_delete=models.CASCADE)
    user_id    = models.ForeignKey('users.User', on_delete=models.CASCADE)
    rating     = models.DecimalField(max_digits=2, decimal_places=1)
    content    = models.CharField(max_length=1000)

Product 객체는 Comment 객체를 정참조하고 있으므로, 속성 이름으로 바로 접근이 가능합니다.

Comment1 = Comment.objects.get(id=1)
Comment.product.name
> '지구 끝의 온실'

그러나 Comment 객체는 Product 객체를 역참조하고 있으므로, [classname]_set 이라는 속성으로 접근해야 합니다.

특정 상품에 대한 코멘트들에 접근해봅시다.

class ProductView(View):
      def get(self, request, product_id)

      product = Product.objects.get(id = product_id)
      comments = product.comment_set.all()

이때 comment_set 대신 related_name 을 사용하면 좀 더 깔끔하게 코드를 구현할 수 있습니다.

related_name 이란?

정참조하고 있는 클래스의 인스턴스에서 어떤 명칭으로 거꾸로 호출당할지 정해주는 이름입니다.

Comment 객체의 product_id 라는 속성에 Product 객체가 연결되어 정참조하고 있습니다. Product 객체의 인스턴스와 연결되어있는 Comment 객체를 거꾸로 불러올 때, reviews라는 이름으로 부르기 위해 related_name을 지정해 줍니다.

class Comment(TimeStampModel):
    product_id = models.ForeignKey('products.Product', on_delete=models.CASCADE, related_name = 'review')
    user_id    = models.ForeignKey('users.User', on_delete=models.CASCADE)
    rating     = models.DecimalField(max_digits=2, decimal_places=1)
    content    = models.CharField(max_length=1000)

때에 따라, 참조하고 있는 객체 이름에 _set을 붙이는 것이 더 직관적인 경우가 굉장히 많기 때문에 모든 Foreign Keyrelated_name을 붙여줄 필요는 없습니다.

한 class에서 서로 다른 두 컬럼이 같은 테이블을 참조하는 경우,
_set이라는 속성만으로는 자신을 바라보고 있는 객체 중 어떤 속성에 접근해야하는지 알 수가 없기 때문에 Related_name이 반드시 필요합니다.

profile
내가 나여서 빛이나기 위해😊

2개의 댓글

comment-user-thumbnail
2021년 11월 14일

오... 엄청 쏙쏙들어와요..!

1개의 답글