The pattern <modelo>_set
or default_related_name
is essentially responsible for making the reverse relationship of one (its object q
instantiated from the class Question
) for many (0 or more class created objects Choice
associated with the class instance Question
by relationship of ForeignKey
).
In short, when the foreign key relationship is established (or ForeignKey
above) in the model Choice
pointing to the model Question
automatically a one to many relation is established from the property choice_set
(Choice based on the name of the adjacent model, always in lowercase) in the instance q
.
As you originally observed, when using the method q.choice_set.create
the object q
will be automatically injected into the creation of the related class objects (Choice
); analogously, when accessing the method q.choice_set.all
you will be informing the framework that you want to get all class objects Choice
that are related to the instance q
specifically.
It is important to note that Choice.objects.all
is different from q.choice_set.all
in this case: the first will be getting all the objects of the class Choice
without filtering the relationship with the class Question
; in the second, as stated in the previous paragraph, a filter is basically established to obtain only the data related to the instance q
.
To illustrate all this, note the following case:
from django.utils import timezone
# Criando um objeto Question
q = Question.objects.create(question_text='Que faz agora?', pub_date=timezone.now())
# Criando escolhas (Choice) relacionadas ao objeto Question
q.choice_set.create(choice_text='Programando', votes=0)
q.choice_set.create(choice_text='Jogando', votes=0)
'''
Demonstrando a criação de um novo objeto Question em que é definida
a associação diretamente na criação dos objetos Choice respectivos
'''
q2 = Question.objects.create(question_text='De onde fala?', pub_date=timezone.now())
Choice.objects.create(question=q2, choice_text='Brasil', votes=0)
Choice.objects.create(question=q2, choice_text='EUA', votes=0)
Finally, getting the Choice
s, we have the following results:
# Obtendo as escolhas (Choice) da pergunta (Question) 'Que faz agora?'
>>> q.choice_set.all()
<QuerySet [<Choice: Programando>, <Choice: Jogando>]>
# Mesma coisa para a pergunta 'De onde fala?'
>>> q2.choice_set.all()
<QuerySet [<Choice: Brasil>, <Choice: EUA>]>
# Obtendo os objetos Choice sem filtrar por qualquer dos Question relacionados
>>> Question.objects.all()
<QuerySet [<Choice: Programando>, <Choice: Jogando>, <Choice: Brasil>, <Choice: EUA>]>