0

我之前问过这个问题,但我没有收到任何解决方案,所以这次我试图让问题更简洁明了。

我的数据库具有以下简化架构:

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 , userlanguageversion 可以有很多 languagecode , flag 可以有很多 languagecode 。

使用select_related不会返回flag.flagIconPath因为一对多的关系,所以 Django 文档状态我必须使用prefetch_related,并带有一对多外键的相关名称。

所以我在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 %}

但是,这段代码什么也不返回。

谁能提供一些建议,因为我看不到我做错了什么?

4

1 回答 1

2

我建议您使用 django shellpython 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')

有了所有这些嵌套调用,那么远的预取就可以......进行巨大的查询。你确定这是你想要的吗?

于 2012-05-17T03:14:36.883 回答