Django 查询集总是重新加载实例

Django queryset always reload instances

我在使用自制缓存描述符和调试时遇到了一些问题,我想到了这个我无法理解的(奇怪的)行为。考虑以下 Django1.7 模型(实际上与我的原始项目相比非常简化):

class Step(models.Model):
    game = models.ForeignKey('Game', on_delete=models.PROTECT)
    number = models.PositiveIntegerField()
    is_active = models.BooleanField(default=False)

    def __str__(self):
        return '{0}'.format(id(self))

如果在航站楼 I 运行 python manage.py shell 然后

In [1]:ss = Step.objects.filter(game=1)

In [2]: ss
Out[2]:[<Step: 139934116973392>, <Step: 139934116971472>]

In [17]: ss[0]
Out[17]: <Step: 139934117084944>

In [18]: ss[0]
Out[18]: <Step: 139934117098512>

In [19]: ss[0]
Out[19]: <Step: 139934117098320>

我不明白为什么 ss[0] id 不断变化...这是标准行为吗?似乎每次访问 ss 时,所有步骤实例时代都会从数据库中重新加载(因此,django.db.connection.queries 始终包含新项目)。

它们是,因为查询集未完全评估和缓存(打印它不会缓存结果)。因此,每次访问 ss[0]:

时都会执行查询
>>> ss = Step.objects.filter(game=1)
>>> ss
[<Step: 139934116973392>, <Step: 139934116971472>]
>>> print ss._result_cache
None
>>> bool(ss)
True
>>> print ss._result_cache
[<Step: 139934117084944>, <Step: 139934117098512>]

只有当查询集被完全评估时(通过遍历它或调用 lenlistbool),结果才会被缓存。