django模板循环中的get_profile会导致许多SQL请求

时间:2012-08-30 09:57:46

标签: django performance django-templates

在django模板中,当您执行循环以显示许多用户的配置文件信息时,您调用get_profile,从而生成尽可能多的SQL请求:

{% for user in users %}
{{ user.username }} : {{ user.get_profile.birth_date }}
{% endfor %}

如果要显示50个用户,它将生成50个SQL请求以获取每个用户的配置文件。

是否有一种减少请求数量的优雅方法?

编辑:

最终目标是管理列表中项目具有用户对象作为属性的项目。 示例:stackoverflow中的每个问题都有一个用户作为创建者。如何在最少的SQL请求中显示用户配置文件信息时列出所有最近的问题:

模板应该是这样的:

{% for question in recent_questions %}
{{ question.title }}
{{ question.body }}
{{ question.creator.username }}
{{ question.creator.get_profile.age }}
{{ question.creator.get_profile.country }}
{% endfor %}

但这会产生太多的SQL请求......

4 个答案:

答案 0 :(得分:1)

我会为这种情况编写自己的模板标签,

@register.simpletag(takes_context=True)
def load_profiles(context,users):
    context['profiles']=ProfileClass.objects.select_related().filter(user__in=users)
    return ''

模板:

{% load_profiles users %}
{% for one in profiles%}
    {{one.user.username}} : {{one.birth_date }}
{% endfor %}

答案 1 :(得分:1)

我认为你可以使用select_related查询。但我不确定.get_profile()是否会使用缓存实例命中数据库。在这种情况下,我建议您使用select_related在视图中查询配置文件列表,以便profile.user缓存并可用,并将配置文件列表传递给模板而不是用户列表。

答案 2 :(得分:0)

它不是特别优雅,但您可以在视图中使用raw()来获取一个请求中的数据:

users = User.objects.raw("SELECT **the data you want**, birth_date FROM auth_user,
    app_userprofile as p WHERE p.user_id=auth_user.id"

答案 3 :(得分:0)

{% for profile in profiles  %}
{{ profile.user.username }} : {{ profile.birth_date }}
{% endfor %}