Django queryset总是重新加载实例

时间:2015-03-13 19:11:20

标签: python django django-models django-queryset

我遇到了一些自制缓存描述符的问题和调试我遇到了这个(奇怪的)行为我无法弄清楚。考虑以下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))

如果在终端我运行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始终包含新项目。)

1 个答案:

答案 0 :(得分:0)

它们是,因为查询集未完全评估和缓存(打印它不会缓存结果)。因此,每次访问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),才会缓存结果。