Python 当我访问一个对象时,Django是否命中了数据库';s属性?

Python 当我访问一个对象时,Django是否命中了数据库';s属性?,python,django,django-models,Python,Django,Django Models,下面的代码是否每次调用question.name时都会查询数据库 class Question(models.Model): name=models.CharField() test=models.ForeignKey(Test) questions = Question.objects.filter(test=some_test) for question in questions: question_name = question.name “我的观点”采用一组问

下面的代码是否每次调用question.name时都会查询数据库

class Question(models.Model):
    name=models.CharField()
    test=models.ForeignKey(Test)

questions = Question.objects.filter(test=some_test)
for question in questions:
    question_name = question.name

“我的观点”采用一组问题和用户回答,并在工作表中打分。我的目标是在不返回数据库的情况下执行所有评分,然后使用后台任务保存比较结果(一个字典),如果需要更长的时间就可以了。我想消除任何不必要的数据库点击。

好吧,你的问题不清楚,但可以肯定的是,至少需要对数据库进行一次点击。事实上,在您的代码示例中,您使用:

question_name = question.name
但是,如果
question
不是
question
模型的一个实例,我就看不出这是可行的

因此,考虑到您在创建实例的查询中对数据库的最初点击,
question\u name
可以根据需要随时重复使用,而无需访问数据库。请参见,这是一个数据库行的静态实例

编辑

现在对于您的编辑,它不是相同的行为。要正确理解幕后发生的事情,你需要理解“懒惰”的概念。事实上,由于查询集在Django中是惰性的,所以这行代码:

questions = Question.objects.filter(test=some_test)
不会对数据库造成任何影响。Querysets代表SQL查询集。因此,在这一点上,由于您没有要求从数据库中获取某些内容,因此实际上还没有对其进行评估。这是需要的行为,因为它确保仅在需要时访问数据库。如图所示,以下是对查询集进行评估的案例:

迭代

QuerySet是可编辑的,它首先执行其数据库查询 当你迭代它的时候

切片

切片一个未计算的查询集通常会返回另一个未计算的查询集 QuerySet,但如果使用 切片语法的“step”参数,并将返回一个列表。切片 已计算的QuerySet还返回一个列表

酸洗/缓存

repr()。当您对查询集调用repr()时,将对其求值。这是 为了方便使用Python交互式解释器,您可以 以交互方式使用API时,立即查看结果

len()。当您对查询集调用len()时,将对其求值。这个,就像你 返回结果列表的长度

列表()。通过对查询集调用list()强制对其求值

bool()。在布尔上下文中测试查询集,例如使用bool(), or、and或if语句将导致执行查询


所以,正如你所看到的,情况1适用于你的特殊情况。迭代将导致对数据库的点击

谢谢,我编辑了。这是否让事情变得更清楚一点?你确实回答了我的问题。因此,对
question
的实例调用
question.name
不会再次命中数据库,因为我检索到的问题已经包含了该行中的所有信息。嗯,您可以尝试上面的代码,但我怀疑它是否有效,因为将返回queryset实例,并且不可能像您那样对其进行迭代。代码是否像您发布的那样工作?我一直在迭代类似的查询集!对不起,我错了你的编辑。很好。但是为了回答您的问题,在这种情况下,它每次都会命中数据库。请看我的编辑。谢谢,这些信息正是我想弄明白的!顺便说一下,这是一个非常好的问题!干得好在我看来,应该会产生更多的流量,希望我能帮上忙。