这个Django应用教程中的choice_set是什么?
在Django的教程中,有这么一句话,来自于 写你的第一个Django应用,第一部分:
p.choice_set.create(choice='Not much', votes=0)
那么,choice_set
是怎么产生的,它是什么呢?
我猜choice
部分是教程中使用的模型Choice
的小写版本,但choice_set
又是什么呢?能详细解释一下吗?
2 个回答
这里提出了两个重要的问题。
第一个:choice_set
是怎么产生的?
第二个:它是什么?
我会分享我第一次学习时是如何让自己理解得更简单的。先回答第二个问题,“它是什么”,我用这三个词来解释:模型实例、与该实例相关的对象集合、相关管理器。
这是Django教程中的Models.py:
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
实例:
q = Question.objects.get(pk=3)
# Here q is an instance of model class 'Question'.
c = Choice.objects.get(pk=32)
# Here c is an instance of model class 'Choice'.
模型实例就是你数据库中整个表的一行数据。
在这里,Question Model
作为Choice Model
的外键
使用。因此,所有与实例q相关的对象集合可以通过以下方式进行筛选:
q.choice_set.all()
所以,choice_set
指的就是与主键为3的问题相关的所有选择。
现在,回答第一个问题需要用到第三个词相关管理器。Django文档中提到的内容在这里:
如果一个模型有外键,那么外键模型的实例将可以访问一个管理器,这个管理器会返回第一个模型的所有实例。默认情况下,这个管理器的名称是FOO_set,其中FOO是源模型的名称,全部小写。这个管理器返回的查询集可以像上面“检索对象”部分所描述的那样进行筛选和操作。
这个词(choice_set)可以通过外键中的'related_name'参数进行更改。
question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name="choices")
对于通过外键的反向关系:
q.choice_set.all()
# If using related_name, then it is the same as
q.choices.all()
# All the choices related to the instance q.
对于正向关系:
choice_qs = Choice.objects.all()
choice_qs.filter(question=q)
# Same result as above. All the choices related to instance q.
你在 Choice
上创建了一个外键,这个外键把每个选择和一个 Question
关联起来。
所以,每个 Choice
都有一个明确的 question
字段,这个字段是在模型中定义的。
Django 的对象关系映射(ORM)也会从 Question
反向跟踪这个关系,自动在每个实例上生成一个叫 foo_set
的字段,其中 Foo
是有外键指向这个模型的模型。
choice_set
是一个 RelatedManager
,它可以创建与 Question
实例相关的 Choice
对象的查询集,比如你可以用 q.choice_set.all()
来获取所有相关的选择。
如果你不喜欢 Django 自动选择的 foo_set
这个名字,或者如果你有多个外键指向同一个模型,需要区分它们,你可以使用 related_name
参数在 ForeignKey
中自定义一个名字。