之前我问过这个问题,但我没有收到任何解决方案,所以我试图让问题简明扼要。这次更清楚。
我的数据库具有以下简化架构:
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可以有很多语言代码,而flag可以有很多语言代码。
使用 select_related 不会返回 flag.flagIconPath 因为1对多关系,所以Django docs状态我必须使用 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 %}
但是,这段代码什么也没有返回。
任何人都可以提供一些建议,因为我看不出我做错了什么?
答案 0 :(得分:2)
我建议您使用django shell python manage.py shell
来计算您的查询 - 通过模板“弄明白”将很难解决错误。
例如,您看起来有拼写错误,但模板不会抱怨它。
让我们将您尝试的查询分解为python,以便我们可以使用注释
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')
对于所有这些嵌套调用,一个预取,它可以做出巨大的查询。你确定这是你想要的吗?