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を使用しても、1 対多の関係のために flag.flagIconPath が返されないため、Django のドキュメントには、1 対多の外部キーの関連名を使用して 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 シェル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)

このクエリをより効率的にするには、select 関連の呼び出しに、これらのモデルを介したフル パスを含める必要があります。元のモデルのすべての外部キーであるかのように、属性を渡しています。

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

この時点でのプリフェッチ呼び出しについてはわかりませんが、おそらく次のようになるはずです

qs.prefetch_related('userLanguageVersionID__languageCodeID__flag_languageCodeID')

これらのネストされた呼び出しのすべてで、これまでのプリフェッチは巨大なクエリを作成する可能性があります。これでよろしいですか?

于 2012-05-17T03:14:36.883 に答える