2012-08-30 25 views
3

在Django模板,當你做一個循環來爲衆多用戶顯示的個人資料信息,你叫get_profile,從而產生儘可能多的SQL請求:get_profile在Django模板循環導致許多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請求......

回答

1

我會寫我自己的templatetag這種情況下,

@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 %} 
+0

我把這個問題做了精度:在我的情況下,循環在配置文件是不可能的 – Eric

1

我認爲你可以使用select_related查詢。但我不確定.get_profile()是否會使用緩存實例命中分貝。在這種情況下,我建議您使用select_related查詢視圖中的配置文件列表,以便profile.user被緩存並可用,並將配置文件列表傳遞給模板而不是用戶列表。

0

它不是特別優雅,但你可以使用原始()在視圖中獲得一個請求的數據:

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" 
0
{% for profile in profiles %} 
{{ profile.user.username }} : {{ profile.birth_date }} 
{% endfor %} 
+0

我提出了一些精度的問題:在我的情況下,配置文件循環是不可能的 – Eric