2012-05-17 25 views
0

我之前問過這個問題,但我沒有收到任何解決方案,所以我試圖讓這個問題簡潔明瞭些,&。新手第一次嘗試prefetch_related - 返回空白

我的數據庫具有以下簡化架構:

class RIAchievement(models.Model): 
    riAchievementID = models.AutoField(primary_key=True, db_column="riAchievementID") 
    userLanguageVersionID = models.ForeignKey(UserLanguageVersion, db_column="userLanguageVersionID", related_name="riAchievement_userLanguageVersionID") 
    class Meta: 
    db_table="riAchievement" 

class UserLanguageVersion(models.Model): 
    userLanguageVersionID = models.AutoField(primary_key=True, db_column="userLanguageVersionID") 
    languageCodeID = models.ForeignKey(LanguageCode, db_column="languageCodeID", related_name="userLanguageVersion_languageCodeID") 
    class Meta: 
    db_table="userLanguageVersion" 

class LanguageCode(models.Model): 
    languagecodeID = models.AutoField(primary_key=True, db_column="languageCodeID") 
    class Meta: 
    db_table="languageCode" 

class Flag(models.Model): 
    flagID = models.AutoField(primary_key=True, db_column="flagID") 
    languageCodeID = models.ForeignKey(LanguageCode, db_column="languageCodeID", related_name="flag_languageCodeID") 
    flagIconPath = models.CharField(max_length=255, db_column="flagIconPath") 
    class Meta: 
    db_table="flag" 

從本質上講,riachievement可以有很多userlanguageversion S和userlanguageversion可以有很多語言代碼S和標誌可以有很多語言代碼秒。

使用select_relatedflag.flagIconPath不返回,因爲1到一對多的關係,所以Django文檔狀態,我必須使用prefetch_related,與相關名稱1許多外鍵。

所以我修改我的代碼在我view.py

from django.shortcuts import render 
from app_data.models import RIAchievement 

def ri_achievements(request): 

    qs = RIAchievement.objects.select_related("riachievement", "userlanguageversion", "languagecode", "flag_languageCodeID").all() 

    return render(request, 'index.html',{'qs': qs}) 

而且我的index.html

{% for ri_achievement in qs %} 
    {{ ri_achievement.userLanguageVersionID.langaugeCodeID.flag_languageCodeID.flagIconPath }} 
{% endfor %} 

但是,這個代碼沒有返回。

任何人都可以提供一些建議,因爲我不明白我做錯了什麼?

回答

2

我建議你使用django shell python manage.py shell來找出你的查詢 - 通過模板「解決」它是非常困難的,因爲它可以抑制錯誤。

例如,它看起來像你有一個拼寫錯誤,但模板不會抱怨它。

讓我們打破你試圖查詢到蟒蛇,使我們可以使用註釋

flagIconPath = (ri_achievement 
    .userLanguageVersionID # correct. direct FK 
    .langaugeCodeID # spelling error. but otherwise ok. direct FK 
    # this is now a one to many relationship - you now have a related manager 
    # NOT a single object. Many flags to one Code 
    .flag_languageCodeID 
    .latest('id') # you must pick which one you want - for example, the latest ID 
    .flagIconPath) 

至於使這個查詢的效率,你的選擇與調用將需要包括通過這些模型的完整路徑。您正在傳遞屬性,就好像它們是原始模型上的所有外鍵一樣。

qs = RIAchievement.objects.select_related('userLanguageVersionID__languageCodeID') 

我不能確定在這一點上預取通話,但它可能應該是這個樣子

qs.prefetch_related('userLanguageVersionID__languageCodeID__flag_languageCodeID') 

所有這些嵌套調用的,預取,遠遠可以..做一個巨大的查詢。你確定這是你想要的嗎?

+0

Yuji,謝謝你的迴應。這給了我一個前往的方向,並解決了我遇到的一些問題。 – user1261774