【问题标题】:Django - query multi-level foreign keysDjango - 查询多级外键
【发布时间】:2018-06-12 19:10:47
【问题描述】:

我正在尝试理解在Django中查询多级外键表的概念,我真的希望有人可以帮助我。

所以,我正在尝试在 Django 中创建一个列表视图,其中显示玩家、他们的分数和一些相关信息,例如他们的专业水平。数据库结构如下:

Players Table
-------------
id
name
<field 1>
<field 2>
<field N>

然后有一个表格存储玩家的分数

Player Scores Table
-------------------
id
player_id (this refers to player.id field from table above)
score
level_id (this refers to a level.id field from table below)

还有一个像下面这样的等级表:

Level Table
-----------
id
level_text

我想要的是创建如下列表:

Player Name   Player Score    Player Level
-----------   -------------   ------------
Blue_Marvel   10000           Maestro
Man_At_Arms   51              Noob
P_K_In_Debt   1230000         God 

您可以猜到,这三列中每一列的数据都需要来自三个不同的表。

我对 Django 很陌生,只能执行一些基本查询。我知道我可以做到Player.object.all() 并且我得到了所有玩家(定义了一个玩家模型)。同样,我可以通过Level.object.all() 获得所有专业水平。

但是我不确定如何继续构建一个包含玩家姓名、分数和级别文本的列表,例如上面的列表。

感谢任何帮助。假设有一个 Level 和 Score 模型,我有没有一种简单的方法来创建上面的列表?如果这些模型不可用,Django 查询是否有任何巧妙的方法来实现这一点?

如果有任何指点,我将不胜感激!

【问题讨论】:

  • 但是每一行都映射在 PlayerScore 行上,对吧?
  • 如果您发布实际模型,您的问题会更清楚。
  • @WillemVanOnsem 是的,每一行都映射到一个玩家得分。显示特定游戏事件的分数。
  • @DanielRoseman - 不幸的是,我什至不知道模型的位置,这是一个非常古老的 django 应用程序,随着时间的推移由许多开发人员开发......我遇到了许多与这些相关的模型表。我试图了解如何在模型可用的情况下查询这些
  • 好吧,在不了解模型的情况下,您无法编写查询。

标签: python django django-views foreign-keys


【解决方案1】:

对我来说,这看起来像您想要一个实际映射到 PlayerScore 表上的 ListView:对于表中的每一行,输出中都有 一个 行,反之亦然。

使这种情况更特别的唯一想法是,我们也想获取玩家姓名。通常,您可以通过在要选择的值上使用 .annotate(..) 来执行此操作。所以我们可以在这里定义一个ListView [doc]

# views.py

from django.db.models import F

class PlayerScoreListView(ListView):

    model = PlayerScore
    template = '/app/playerscore_list.html'
    queryset = PlayerScore.objects.annotate(
        player_name=F('player__name'),
        level_name=F('level__name')
    )

所以每次我们也会获取player__name列,以及level__name. If you definedplayerandlevelasForeignKeys to thePlayermodel andLevelmodel respectively, Django will automatically make the JOINs at database level, and these are stored in thePlayerScoreinstances as.player_name@ 987654335@.level_name` 属性。

我们唯一需要做的就是定义一个模板。例如:

{% app/templates/app/playerscore_list.html %}

<html>
<body>
<table>
 <thead>
  <tr>
     <th>Player name</th>
     <th>Score</th>
     <th>Level name</th>
  </tr>
 </thead>
 <tbody>
 {% for item in object_list %}
  <tr>
     <td>{{ item.player_name }}</td>
     <td>{{ item.score }}</td>
     <td>{{ item.level_name }}</td>
  </tr>
 {% endfor %}
 </tbody>
</table>
</body>
</html>

当然我们还需要链接一个 URL 到这个视图:

# urls.py

from django.urls import path

from app.views import PlayerScoreListView

urlpatterns = [
    path('playerscore/', PlayerScoreListView.as_view(), name='playerscorelist'),
]

当然,上面是一个“原始”实现。为了显示所有相关内容,并使页面看起来“愉快”,还有一些工作要做。

【讨论】:

  • 我非常感谢您的帮助!我会试试这个,让你知道它是怎么回事,再次感谢!
猜你喜欢
  • 2020-08-17
  • 2012-05-22
  • 1970-01-01
  • 2011-02-01
  • 2018-09-01
  • 2015-03-09
  • 1970-01-01
  • 2019-03-15
  • 2011-10-20
相关资源
最近更新 更多