장고(Django) 역참조를 위한 '모델명_set'
장고에서 related_name을 지정하지 않았을 때, 기본적으로 외래키(ForeignKey)를 통해 연결된 모델의 데이터를 참조하기 위해 사용되는 기본 명명 규칙이 모델명_set입니다. 이 규칙은 역참조(reverse relationship)를 위한 것입니다. 이를 통해 외래키 관계로 연결된 모델에서 연결된 데이터를 쉽게 조회할 수 있습니다.
기본 개념
- Forward Relationship(정방향 관계): 외래키가 정의된 모델에서 외래키가 참조하는 모델의 데이터를 참조할 때 사용됩니다.
- 예: answer.question (Answer 모델에서 Question 모델을 참조)
- Reverse Relationship(역방향 관계): 참조된 모델에서 외래키가 정의된 모델의 데이터를 참조할 때 사용됩니다.
- 예: question.answer_set (Question 모델에서 연결된 Answer 모델 데이터를 조회)
예시
다음과 같은 두 모델이 있다고 가정해 보겠습니다.
from django.db import models
class Question(models.Model):
subject = models.CharField(max_length=200)
content = models.TextField()
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
content = models.TextField()
위 예시에서 Answer 모델은 Question 모델과 외래키(ForeignKey)로 연결되어 있습니다. 여기서 중요한 점은 Answer 모델에서 question 필드를 사용해 정방향으로 Question 모델을 참조할 수 있습니다.
역참조를 위한 '모델명_set'
그러나 Question 모델에서 연결된 모든 Answer 객체를 조회하고 싶을 때는 기본적으로 장고가 제공하는 answer_set을 사용해야 합니다. 즉, Question 모델에서 역참조할 때 Answer 모델을 찾는 방식입니다.
예시: 모델명_set 사용
# Question 객체 하나를 가져옴
question = Question.objects.get(id=1)
# 해당 Question과 연결된 모든 Answer 객체를 역참조로 가져옴
answers = question.answer_set.all() # answer_set을 통해 연결된 Answer 객체를 모두 가져옴
# 출력
for answer in answers:
print(answer.content)
여기서 answer_set은 장고가 자동으로 생성한 기본 이름입니다. _set은 모델명(소문자) 뒤에 붙는 형식입니다. question.answer_set을 호출하면 해당 질문(Question)에 연결된 모든 답변(Answer)이 반환됩니다.
related_name을 사용하여 이름 지정
장고에서 기본적으로 제공하는 모델명_set 대신에, 명시적으로 역참조 이름을 지정할 수 있습니다. 이를 위해 related_name 옵션을 사용합니다.
related_name 사용 예시:
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name='answers')
content = models.TextField()
이렇게 related_name='answers'로 지정하면 이제 question.answer_set 대신 question.answers로 역참조할 수 있습니다.
related_name 사용 예시:
# Question 객체 하나를 가져옴
question = Question.objects.get(id=1)
# 해당 Question과 연결된 모든 Answer 객체를 역참조로 가져옴
answers = question.answers.all() # 'answers'로 지정된 이름 사용
# 출력
for answer in answers:
print(answer.content)
정리:
- 모델명_set: 장고에서 기본적으로 외래키로 연결된 모델을 역참조할 때 사용하는 기본 방식입니다.
- 예: question.answer_set.all() → Question 객체에서 연결된 Answer 객체들을 가져옴.
- related_name: 기본적으로 제공되는 _set 대신, 더 직관적인 이름을 사용하고 싶을 때 related_name 옵션을 통해 원하는 이름을 지정할 수 있습니다.
- 예: question.answers.all() → related_name='answers'로 설정하여 더 명시적인 이름을 사용.
언제 사용하나요?
- 모델명_set은 장고에서 자동으로 설정하는 역참조 명칭이기 때문에, related_name을 지정하지 않으면 기본적으로 사용됩니다.
- 다수의 외래키가 동일한 모델을 참조할 경우에는 related_name을 통해 명시적으로 역참조 이름을 지정하는 것이 좋습니다. 이렇게 하면 코드 가독성이 높아지고, 중복된 _set으로 인한 혼란을 피할 수 있습니다.
이 방식은 외래키로 연결된 두 모델 간의 관계를 더 쉽게 관리하고 조회할 수 있도록 돕습니다.