DjangoのListViewに関して
DjangoのLivewViewのまとめ
すぐに忘れてしまうので、LivewViewについて備忘録としてまとめておく
公式サイトのLivewViewの説明
ListViewのコード
GitHubのListViewのコードです。バージョン5.1です
ListView
ListViewはDjangoの組み込みViewです。ListViewを継承したViewにおいて、オブジェクトのリストを表示するために利用します。テンプレートに複数のオブジェクトを保持するQuerySetをわたします
簡単に言うと、指定したモデルクラスの一覧を表示します
前提のモデル
以下のモデルで利用します。以下のカラムを保持します
name, hp, mp, type, birthday
from django.db import models
class Monster ( models.Model ) :
class Meta:
db_table = "monster"
TYPE_CHOICES = (
(1, "炎属性"),
(2, "水属性"),
(3, "闇属性"),
)
name = models.CharField(
max_length=100
)
hp = models.IntegerField(
default=0
)
mp = models.IntegerField(
default=0
)
type = models.IntegerField(
choices=TYPE_CHOICES
)
birthday = models.DateField(
verbose_name="birthday",
)
created_at = models.DateTimeField(
auto_now_add=True,
)
def __str__(self):
return self.name
簡単なListView
最小構成ではないですが、基本形です
- 「model」はモデル名として「Monster」を指定します。未設定の場合、「queryset」を指定するか、「get_queryset」メソッドのオーバーライドが必要です
- template_nameではテンプレートファイルを指定します。デフォルトでは、「モデル名_list.html」になります。アプリ名とモデル名でディレクトリ分割したいのでディレクトリで区切ります
- orderingは一覧表示の並びを指定します。何順でもよいですが、ここでは単純にidの昇順にします
- ページングを10件にします
- テンプレートで利用するquerysetは初期設定で「object_list」です
from django.views.generic import ListView
from .models import Monster
class MonsterListView(ListView):
model = Monster
template_name = "study/monster/list.html"
ordering = "id"
paginate_by = 10
テンプレートファイル
対応するテンプレートファイルです。
- base.htmlを作成して、継承します
- django_bootstarap5を利用します
- Bootstrap5でスタイリングします
- 一覧データを保持するquerysetの変数名は「object_list」です
- 一覧のURL:study:monster_list
- 新規作成のURL:study:monster_create
- 更新のURL:study:monster_update
{% extends "base.html" %}
{% load django_bootstrap5 %}
{% block title%}{{ title }}{% endblock %}
{% block content %}
<div class="container mt-4">
<h2 class="mb-4 p-2 bg-primary text-white">Monster List</h2>
<div class="mb-3">
<a href="{% url 'study:monster_create'%}" class="btn btn-primary">新規作成</a>
</div>
{% bootstrap_pagination page_obj %}
<table class="table table-bordered table-hover">
<thead class="table-dark">
<tr>
<th>ID</th>
<th>NAME</th>
<th>HP</th>
<th>MP</th>
<th>Type</th>
<th>Birthday</th>
<th>詳細</th>
<th>更新</th>
</tr>
</thead>
<tbody>
{% for o in object_list %}
<tr>
<td>{{o.id}}</td>
<td>{{o.name}}</td>
<td>{{o.hp}}</td>
<td>{{o.mp}}</td>
<td>{{o.get_type_display}}</td>
<td>{{o.birthday}}</td>
<td><a href="{% url 'study:monster_detail' o.id %}"class="btn btn-primary">詳細</a></td>
<td><a href="{% url 'study:monster_update' o.id %}"class="btn btn-primary">更新</a></td>
</tr>
{% endfor %}
</tbody>
</table>
{% bootstrap_pagination page_obj %}
</div>
{% endblock %}
querysetを指定する
model, orderingを指定しないで、querysetを指定します。querysetで取得したい一覧を指定します。QuerySetを返す処理を指定します。同時に並び順も指定します。ここでは、全件を取得していますが、filterを利用して、絞り込むことも可能です。また、select_relatedなどを利用して、結合することも可能です。ただし、querysetには、1行の処理しか記述できません
class MonsterListView(ListView):
template_name = "study/monster/list.html"
queryset = Monster.objects.all().order_by("id")
paginate_by = 10
get_querysetをオーバーライドする
model, querysetを指定しないで、get_querysetメソッドをオーバーライドします。より自由度の高い処理を記述可能です
class MonsterListView(ListView):
template_name = "study/monster/list.html"
paginate_by = 10
def get_queryset(self):
qs = Monster.objects.all().order_by("id")
return qs
コンテキストにデータを渡す
get_context_dateメソッドをオーバーライドすることで、コンテキストに追加データを渡すことができます。つまり、テンプレートで利用するデータを指定します
class MonsterListView(ListView):
model = Monster
template_name = "study/monster/list.html"
ordering = "id"
paginate_by = 10
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["title"] = self.__class__.__name__
return context
継承元クラス
以下のクラスを継承しています
django.views.generic.list.MultipleObjectTemplateResponseMixin
django.views.generic.base.TemplateResponseMixin
django.views.generic.list.BaseListView
django.views.generic.list.MultipleObjectMixin
django.views.generic.base.View
メソッドの実行順序
setup()
dispatch()
http_method_not_allowed()
get_template_names()
get_queryset()
get_context_object_name()
get_context_data()
get()
render_to_response()
Discussion