Category/Django

장고(Django) 역참조를 위한 '모델명_set'

Corinee 2024. 9. 11. 14:40
728x90

장고에서 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으로 인한 혼란을 피할 수 있습니다.

이 방식은 외래키로 연결된 두 모델 간의 관계를 더 쉽게 관리하고 조회할 수 있도록 돕습니다.

728x90