Python 当我访问一个对象时,Django是否命中了数据库';s属性?
下面的代码是否每次调用question.name时都会查询数据库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 “我的观点”采用一组问
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实例,并且不可能像您那样对其进行迭代。代码是否像您发布的那样工作?我一直在迭代类似的查询集!对不起,我错了你的编辑。很好。但是为了回答您的问题,在这种情况下,它每次都会命中数据库。请看我的编辑。谢谢,这些信息正是我想弄明白的!顺便说一下,这是一个非常好的问题!干得好在我看来,应该会产生更多的流量,希望我能帮上忙。