데이터베이스에서 두 테이블이 참조 관계에 있는 경우를 생각해봅시다.
예를 들어, 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
을 사용하면 좀 더 깔끔하게 코드를 구현할 수 있습니다.
정참조하고 있는 클래스의 인스턴스에서 어떤 명칭으로 거꾸로 호출당할지 정해주는 이름입니다.
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 Key
에 related_name
을 붙여줄 필요는 없습니다.
Related name이 필수인 경우가 있다.
한 class에서 서로 다른 두 컬럼이 같은 테이블을 참조하는 경우,
_set
이라는 속성만으로는 자신을 바라보고 있는 객체 중 어떤 속성에 접근해야하는지 알 수가 없기 때문에 Related_name이 반드시 필요합니다.
오... 엄청 쏙쏙들어와요..!