简体   繁体   中英

Django - query multi-level foreign keys

I am trying to understand the concept of querying multiple level foreign key tables in Django, and I really hope someone can help me with it.

So, I am trying to create a List view in Django which shows players, their scores and some related information like their level of expertise. The database structure is something like below:

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

Then there is a table which stores the player's scores

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)

And there is a level table like below:

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

What I want is to create a list like below:

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

As you can guess the data for each of these three columns need to come from three different tables.

I am very new to Django and can only perform some basic queries. I know I can do Player.object.all() and I get all the players (there is a player model defined). Similarly I can do Level.object.all() and I get all the expertise levels.

However I am not sure how I can proceed to construct a list such as above with player name, score and level text.

Any help is appreciated. Assuming that there is a Level and Score model, is there an easy way for me to create above list? If these models are not available, does Django query have any nifty way to achieve this?

I would really be grateful for any pointers!

For me, this looks like you want a ListView that actually maps on the PlayerScore table: for every row in the table there is one row in the output and vice versa.

The only think that makes this case more special, is that we want to fetch the player name as well. Typically you can do this by using a .annotate(..) on the values you want to select. So we can here define a ListView [doc] :

# views.py

from django.db.models import 

class (ListView):

    model = PlayerScore
    template = '/app/playerscore_list.html'
    

So each time we will also fetch the player__name column, as well as the level__name. If you defined level__name. If you defined player and level as ForeignKey s to the Player model and Level model respectively, Django will automatically make the JOINs at database level, and these are stored in the PlayerScore instances as .player_name and .level_name` attribute.

The only thing we still need to do, is define a template. For example:

{% 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>
 
  <tr>
     <td>{{ item }}</td>
     <td>{{ item }}</td>
     <td>{{ item }}</td>
  </tr>
 
 </tbody>
</table>
</body>
</html>

Of course we also need to link a URL to this view:

# urls.py

from django.urls import path

from app.views import PlayerScoreListView

urlpatterns = [
    
]

Of course the above is a "raw" implementation. In order to show all relevant content, and make the page look " pleasant ", there still is some work to do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM