well-balanced

[Django Tutorial] choice_set란? (Related objects) 본문

Python

[Django Tutorial] choice_set란? (Related objects)

Cosmian 2020. 1. 31. 04:03

오역이 있을 수 있습니다.

사건은 Django 튜토리얼 진행 도중에 발생했다.

오잉 choice.set이 뭐지?

Tutorial를 따라가면서 Shell을 통해 모델을 제어하고 있는 도중 choice_set이 갑툭튀. 이상하다 난 저런 메소드를 구현한 적이 없는데.. 그래도 혹시 모르니 models.py 파일을 다시 확인해봤으나 역시 없다.

 

처음에는 내장 메소드인줄 알고 문서에서 찾아봤지만 없었고, 좀 찾아보니 이곳에서 이유를 알아낼 수 있었다.

Related objects¶

When you define a relationship in a model (i.e., a ForeignKey, OneToOneField, or ManyToManyField), instances of that model will have a convenient API to access the related object(s).
Using the models at the top of this page, for example, an Entry object e can get its associated Blog object by accessing the blog attribute: e.blog.
(Behind the scenes, this functionality is implemented by Python descriptors. This shouldn’t really matter to you, but we point it out here for the curious.)
Django also creates API accessors for the “other” side of the relationship – the link from the related model to the model that defines the relationship. For example, a Blog object b has access to a list of all related Entry objects via the entry_set attribute: b.entry_set.all().
All examples in this section use the sample Blog, Author and Entry models defined at the top of this page.

 

그리고 조금 더 내려보니 이런 말도 있다.

By default, this Manager is named FOO_set, where FOO is the source model name, lowercased.

 

기본적으로 객체에 접근할 수 있는 매니저의 이름은 모델명(소문자)_set 으로 지어진다고 한다.

부족한 영어 실력이지만, 이해를 돕는다면 ForeignKey로 어떠한 모델 A를 참조하고 있는 모델 B는 그 모델 A에 접근할 때 미리 ForeignKey로 지정해두었던 변수를 통해 접근할 수 있고, 참조되고 있는 모델 B모델 A에 접근할 때 모델명_set의 형태로 접근한다.

 

내가 진행 중이던 프로젝트를 예로 들어보자면

# models.py

class Question(models.Model):
    def __str__(self):
        return self.question_text

    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days = 1)

    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

class Choice(models.Model):
    def __str__(self):
        return self.choice_text

    question = models.ForeignKey(Question, on_delete = models.CASCADE)
    choice_text = models.CharField(max_length = 200)
    votes = models.IntegerField(default = 0)

Question 이라는 모델이 있고 Choice 라는 모델이 있다. Choice의 column이 될 question이라는 변수는 Question 모델을 ForeignKey로써 참조하고 있다. 먼저 Question 모델에서 Choice 모델의 값에 접근해보자.

Question.objects.get(pk=1) // Question 모델에서 pk 값이 1인 row를 가져온다.
<Question: What's up?>

q = Question.objects.get(pk=1) 
q.choice_set.all() // 자신을 참조하는 모델이름을 lowercase_set을 이용해 접근한다.
<QuerySet []>

q.choice_set.create(choice_text='Not much', votes=0) // Choice 모델에 row를 생성
<Choice: Not much>

그럼 이제 반대로 Choice 모델에서 Question 모델의 값에 접근해보자.

c = Choice.objects.get(pk=1) // pk=1인 Choice row를 가져온다.

c
<Choice: Not much>

c.question // 미리 ForeignKey로 정해둔 변수를 통해 Question 모델에 접근한다.
<Question: What's up?>

c.question.question_text
"What's up?"

 

아직 개발 초보단계인 내 입장에서 보자면 Django 공식 튜토리얼 안에서 이에 대한 설명이 너무 부족하지 않았나 라는 생각이 든다. 그래도 이렇게 또 하나하나 찾아보면서 배웠으니 머릿속으로 잘 간직할 수 있을 것 같다.

Comments