related_name
은 일대일 관계나 일대다 관계에서 사용하는 것이 일반적이다.
다대다 관계
에서는 하나의 객체가 여러 개의 연결된 객체를 가지고, 연결된 객체 또한 여러 개의 객체와 관련될 수 있기 때문에 related_name
을 사용하면 이름 충돌이 발생할 수 있다.
다대다 관계
에서 related_name
을 사용하려면 모델 설정 시 모델 간 관계를 잘 정의해줘야한다.
한 모델의 각 객체 인스턴스가 다른 모델의 하나의 객체 인스턴스랑만 연결된다.
from django.db import models
class Husband(models.Model):
name = models.CharField(max_length=100)
marriage_date = models.DateField()
wife = models.OneToOneField('Wife', related_name='rn_husband', on_delete=models.CASCADE)
class Wife(models.Model):
name = models.CharField(max_length=100)
marriage_date = models.DateField()
husband = models.OneToOneField(Husband, related_name='rn_wife', on_delete=models.CASCADE)
남자와 여자를 나타내는 두 모델은 OneToOneField
를 통해 연결되었다.
on_delete=models.CASCADE
는 둘 중 한 데이터만 삭제되도 연결된 데이터도 함께 삭제된다.
related_name
을 사용해서 남자와 여자가 서로를 역참조해서 서로의 정보를 가져올 수 있다.
그럼 데이터베이스에 데이터가 저장되어 있다고 가정하고, alex
라는 남자의 아내 데이터를 가져와보자.
husband_alex = Husband.objects.get(name='Alex', marrige_date = '2023-09-15')
wife_lily = Wife.objects.get(name='Lily', marrige_date = '2023-09-15')
alex_wife = husband_alex.rn_wife
Lily_husband = wife_lily.rn_husband
일대일 관계에서 related_name
을 통해 데이터를 가져올 때는 .get()
이나 .filter()
함수 없이 역참조를 통해 데이터를 가져올 수 있다.
한 쪽에서는 여러 개의 연결을 가질 수 있지만, 다른 쪽에서는 하나의 연결만 가지는 관계
팀과 팀원으로 일대다 관계 모델을 정의해보자.
from django.db import models
class Team(models.Model):
name = models.CharField(max_length=100)
class TeamMember(models.Model):
name = models.CharField(max_length=100)
role = models.CharField(max_length=100)
team = models.ForeignKey(Team, related_name='rn_member', on_delete=models.CASCADE)
팀과 팀원을 나타내는 두 모델은 ForeignKey
를 통해 연결되었다.
on_delete=models.CASCADE
는 ForeignKey
로 참조된 팀 모델 데이터가 삭제되면 참조한 팀원 모델 데이터도 삭제된다.
related_name
을 사용해서 팀과 팀원은 서로를 역참조해서 서로의 정보를 가져올 수 있다.
이번에 팀 프로젝트를 진행했는데, 6조 sixsense 팀 그리고 팀원 데이터가 데이터베이스에 저장되어있다고 생각하고 데이터를 가져오는 것을 해보자.
sixsense_team = Team.objects.get(name='sixsense')
member1_alex = TeamMember.objects.get(name='Alex')
alex = sixsense_team.rn_member.filter(name='Alex')
alex_team = member1_alex.rn_member.filter(name='sixsense')
.get(조건)
함수는 해당 조건을 만족하는 유일한 객체를 가져오는데
만약, 데이터베이스에 해당 객체가 없으면 오류가 발생하기 때문에 filter(조건)
함수를 사용하는 것이 좋다.
하나의 객체가 다른 여러 객체와 관계를 맺을 수 있는 관계형이다. 모델 필드에
ManyToManyField
를 선언하면 중간테이블이 저절로 생긴다. 이 중간테이블은 모델 사이의 관계를 저장하고 관리한다.
from django.db import models
class User(models.Model):
name = models.CharField(max_length=100)
class Post(models.Model):
username = models.ForeignKey('User', related_name='rn_post', on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = models.CharField(max_length=100)
like = models.ManyToManyField('self', related_name="rn_like", blank=True)
bookmark = models.ManyToManyField('self', related_name="rn_bookmark", blank=True)
related_name
을 통해서 데이터를 가져와보자.
alex = User.objects.get(name='Alex')
alex_all_posts = alex.rn_post.all()
alex_first_posts = alex.rn_post.first()
alex_liked_posts = alex.rn_like.all()
alex_bookmarked_posts = alex.rn_bookmark.all()
🥚🐣🐤🐥🐓🐔