Django - запрос многоуровневых внешних ключей - PullRequest
0 голосов
/ 12 июня 2018

Я пытаюсь понять концепцию запросов к многоуровневым таблицам внешних ключей в 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() и получить все уровни опыта.

Однако я не уверен, как мне составить список, такой как выше, с именем игрока, счетом и текстом уровня.

Любая помощь приветствуется.Если предположить, что существует модель уровня и оценки, есть ли простой способ для меня, чтобы создать список выше?Если эти модели недоступны, есть ли у запроса Django какой-нибудь изящный способ добиться этого?

Буду очень признателен за любые указатели!

1 Ответ

0 голосов
/ 12 июня 2018

Для меня это выглядит так, как будто вы хотите ListView, который фактически отображается в таблице PlayerScore: для каждой строки в таблице есть одна строка в выводе и наоборот.

Единственная мысль, которая делает этот случай более особенным, это то, что мы хотим получить имя игрока.Обычно вы можете сделать это, используя .annotate(..) для значений, которые вы хотите выбрать.Таким образом, мы можем здесь определить ListView [doc] :

# views.py

from django.db.models import <b>F</b>

class <b>PlayerScoreListView</b>(ListView):

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

Так что каждый раз мы будем также извлекать столбец player__name, а такжеатрибут 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`.

Единственное, что нам еще нужносделать, это определить шаблон.Например:

{% 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>
 <b>{% for item in object_list %}</b>
  <tr>
     <td>{{ item<b>.player_name</b> }}</td>
     <td>{{ item<b>.score</b> }}</td>
     <td>{{ item<b>.level_name</b> }}</td>
  </tr>
 <b>{% endfor %}</b>
 </tbody>
</table>
</body>
</html>

Конечно, нам также нужно связать URL-адрес с этим представлением:

# urls.py

from django.urls import path

from app.views import PlayerScoreListView

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

Конечно, приведенное выше является «сырой» реализацией.Чтобы показать все релевантное содержимое и сделать страницу « приятной », нужно еще кое-что сделать.

...