Django select_related query does not return all values to the template

Django select_related query does not return all values to the template

我有 2 个模型。 Characters 和 CharactersDetails 来自我正在玩弄的 django 网站。

CharactersDetails 与 Characters 有外键关系

class CharactersDetails(models.Model):
    character_link = models.ForeignKey(Characters)

在我看来,我正在这样做:

'character_info': CharactersDetails.objects.select_related('character_link').filter(character_link_id=pk)

在我的模板中,我只从 CharactersDetails table 中取回字段。

在 manage.py shell 中,我 运行 相同的查询,发现它实际上返回了 CharactersDetails 和 Characters 的字段(这是我想要的),但是当视图获取上下文对象,它只显示来自 CharactersDetails table.

的项目
(looking_for_guild_env)klainn:~/workspace (master) $ python manage.py shell
Python 3.4.3 (default, Nov 17 2016, 01:08:31) 
>>> from players.models import Characters,CharactersDetails
>>> myjunk = CharactersDetails.objects.select_related('character_link').filter(character_link_id=1)
>>> print(myjunk)
<QuerySet [<CharactersDetails: CharactersDetails object>]>
>>> print(myjunk.query)
SELECT "characters_details"."id", "characters_details"."character_link_id", "characters_details"."character_class_id", "characters_details"."character_race_id", "characters_details"."character_level", "characters_details"."character_armory_url", "characters_details"."character_profile_image_url", "characters_details"."character_profile_avatar_url", "characters_details"."character_profile_inset_url", "characters"."id", "characters"."character_owner_id", "characters"."character_name", "characters"."character_realm_id", "characters"."character_faction_id", "characters"."insert_date" FROM "characters_details" INNER JOIN "characters" ON ("characters_details"."character_link_id" = "characters"."id") WHERE "characters_details"."character_link_id" = 1
>>> 

我采用相同的查询并将其粘贴到 manage.py dbshell:

(looking_for_guild_env)klainn:~/workspace (master) $ python manage.py dbshell
sqlite> SELECT "characters_details"."id", "characters_details"."character_link_id", "characters_details"."character_class_id", "characters_details"."character_race_id", "characters_details"."character_level", "characters_details"."character_armory_url", "characters_details"."character_profile_image_url", "characters_details"."character_profile_avatar_url", "characters_details"."character_profile_inset_url", "characters"."id", "characters"."character_owner_id", "characters"."character_name", "characters"."character_realm_id", "characters"."character_faction_id", "characters"."insert_date" FROM "characters_details" INNER JOIN "characters" ON ("characters_details"."character_link_id" = "characters"."id") WHERE "characters_details"."character_link_id" = 1;
1|1|15|7|110|http://us.battle.net/wow/en/character/Stormrage/Peppiwyn/simple|stormrage/219/182881755-profilemain.jpg|stormrage/219/182881755-avatar.jpg|stormrage/219/182881755-inset.jpg|1|3|Peppiwyn|192|0|2017-03-20

我得到了所有字段。但是模板不会传递最后 6 个值。当我将 .values() 添加到查询集的末尾然后执行 a:

时,我可以看到这一点
{{ character_info }}

在我看到的模板中:

<QuerySet [{'id': 1, 'character_profile_image_url': 'stormrage/219/182881755-profilemain.jpg', 'character_race_id': 7, 'character_level': 110, 'character_profile_avatar_url': 'stormrage/219/182881755-avatar.jpg', 'character_profile_inset_url': 'stormrage/219/182881755-inset.jpg', 'character_armory_url': 'http://us.battle.net/wow/en/character/Stormrage/Peppiwyn/simple', 'character_link_id': 1, 'character_class_id': 15}]>

我是不是做错了什么,或者是否有一种特殊的方法可以从模板中调用这些值?

感谢阅读。

执行 select_related('character_link') 不会将属性添加到 character_info 实例,它只是在 character_link 的同时从数据库中获取 character_info,使用内部联接。

在模板中,您访问 character_link 实例 {{ character_info.character_link }}

如果您使用 values(),则必须明确包含来自 character_link 的字段:

.values('field1', 'field2', 'character_link__field', ...)

queryset 方法.values() 不会隐式添加所选外键的属性。这是一个 extract of the documentation:

A few subtleties that are worth mentioning:

  • If you have a field called foo that is a ForeignKey, the default values() call will return a dictionary key called foo_id, since this is the name of the hidden model attribute that stores the actual value (the foo attribute refers to the related model). When you are calling values() and passing in field names, you can pass in either foo or foo_id and you will get back the same thing (the dictionary key will match the field name you passed in).

您需要将字段列为 values('character_link__field1', 'character_link__field2'...) 个参数...或者只是不使用它并处理 ORM 对象,这将使用一次查询中检索到的数据。

使用 django-debug-toolbar 等工具,您可以检查请求以确保在呈现模板时只进行一次 SQL 查询。