视图或模板中的Queryset

时间:2015-09-17 06:12:02

标签: python django django-templates django-views django-queryset

我正在努力加快我的代码。在开发过程中,一切都运行得非常顺利,但是一旦我投入生产,并开始在数据库中添加更多深度的数据,我意识到它的运行速度非常慢。

我在django-toolbar上注意到它运行了大量的查询,它应该只有10-20个。我想知道是否可能是因为我提供了很多内容。

例如,我的代码如下所示:

{% if user.profile.is_admin %}
   ...
{% endif %}

{% for stuff in user.profile.get_somestuff %}
   ...
   {{ stuff.info }}
   {{ stuff.other_info }}
   ...
{% endfor %}

这些中的每一个都执行新查询吗?

我应该在视图中运行get_somestuff的查询,将其传递给上下文吗?我从绩效的角度提问。

2 个答案:

答案 0 :(得分:3)

如果profile.get_somestuff是一项昂贵的操作,并且您在模板中多次调用它,是的,您应该在视图中调用一次,然后通过context将结果传递给模板。

def view(request):
    ...
    stuff = request.user.profile.get_somestuff()
    return render(request, 'page.html', {'stuff': stuff})

或者,您可以使用{% with %}标记在其自己的上下文中创建包含值的范围:

{% with stuff=user.profile.get_somestuff %}
   ...
   {{ stuff.info }}
   {{ stuff.other_info }}
   ... do some other things with stuff
{% endwith %}

就个人而言,我会选择第一个选项,因为在django.db.connection.queries的帮助下,监视您在视图中进行的数据库查询相对容易一些。确保尽可能避免发送模板查询集,惰性表达式等。

顺便说一句,请注意DEBUG必须设置为True connection.queries才能正常工作。

答案 1 :(得分:3)

如果stuff.info或stuff.other_info是其他模型的外键,那么是,每次你点击每个模型的新东西时,你可以为每个模型做另一个选择查询。

select_related可能会对您有所帮助。它会有效地连接您在sql查询中预先指定的fk字段上的相关表。 SQL查询将比您现在运行的查询更复杂,但数量要少得多。