django中的'with'标签问题

时间:2012-03-14 18:05:27

标签: django templates tags

我的模型“Invoice”带有方法

def item_objects(self):
    return self.invoiceitem_set.filter(kind='item')

然后我在其上下文“invoice”

中有一个模型

在该模板中,我使用with标签尝试缓存item_objects

{% with item_object=invoice.item_objects%}
    {{item_object}}
    {{item_object}}
{% endwith %}

无论我每次拨打{{item_object}}

,我都会点击数据库

我做错了什么?

1 个答案:

答案 0 :(得分:1)

您的简化代码很可能隐藏了问题,因为您描述的行为不应该发生。 with模板标记的整个目的是缓存昂贵方法的结果,以便以后使用。

但是,您的方法item_objects会返回QuerySet,当您将其分配给item_object时,它仍然是QuerySetQuerySet是延迟加载的,所以到目前为止,还没有数据库命中。因此,根据您使用item_object实际执行的操作,您可能会对查询效果产生负面影响。

例如,即使您正在处理缓存的QuerySet,以下内容也会导致对DB的两次查询:

{{ item_object.count }}
{{ item_object|first }}

您需要注意对查询集执行的操作以及操作顺序。例如,如果您知道您将在某个时刻循环查询集,但是您需要先计算,那么使用{{ item_object|length }}代替{{ item_object.count }}

实际上更有效率