Django - 查询多级外键

时间:2018-06-12 19:10:47

标签: python django django-views foreign-keys

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

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

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查询是否有任何方法可以实现这一目标?

我真的很感激任何指针!

1 个答案:

答案 0 :(得分:1)

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

唯一能让这个案例更加特殊的想法是,我们也希望获取玩家名称。通常,您可以对要选择的值使用.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 defined播放器and级别as ForeignKey s to the播放器{{1} }级别model and PlayerScore model respectively, Django will automatically make the JOINs at database level, and these are stored in the。player_name instances as。level_name`属性。

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

and

当然,我们还需要将URL链接到此视图:

{% 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>

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