【问题标题】:Queryset in view or in template视图或模板中的查询集
【发布时间】:2015-12-13 22:14:25
【问题描述】:

我正在尝试加快我的代码速度。在开发中,一切都运行得很顺利,但是一旦我将它投入生产,并开始向数据库中添加更多深度的数据,我就意识到它运行得很慢。

我在 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 的查询,并通过上下文传递它吗?我是从性能的角度来问的。

【问题讨论】:

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


    【解决方案1】:

    如果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 工作。

    【讨论】:

    • 我感觉这正是我的问题。看起来我有很多优化工作要解决我的所有错误。
    【解决方案2】:

    如果 stuff.info 或 stuff.other_info 是其他模型的外键,那么是的,每次您点击其中的每一个以获取新的东西 obj 时,您可能会为每个模型执行另一个选择查询。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-20
      相关资源
      最近更新 更多