DjangoのListViewのうまい使い方【Python】
- 作成日: 2020-12-09
- 更新日: 2023-12-26
- カテゴリ: Django
DjangoのListViewの使い方
PythonのWebフレームワークであるDjango(ジャンゴ)には、開発者の負担を減らすためのモジュールがいくつも定義されています。
今回紹介するListView(リスト・ビュー)はその内の1つです。
ListViewはDjangoのジェネリック(汎用)・ビューの1つです。
このListViewを使うことでオブジェクトを一覧表示するページの作成を簡単に行うことが出来ます。
この記事ではListViewについて具体的に↓を見ていきます。
- ListViewの概要
- モデルの作成
- オブジェクトの作成
- ListViewによるビューの作成
- その他のListViewの機能
前提
今回はmyapp
というアプリケーション内にビューを作っていきます。
このmyapp
はpython manage.py startapp
で作成済みの前提です。
ListViewの概要
ListViewはその名の通りリストのためのビューで、クラスです。
データーベースに保存されているオブジェクトをユーザーの画面に一覧表示するときに使います。
ListViewはdjango.views.generic
モジュールの中にあります。
よってdjango.views.generic
モジュールからListView
クラスをインポートすることで使うことができます。
ListViewはリスト表示のためのいろいろな手続きを半自動で行います。
必須の属性はmodel
だけで、ここにはリスト表示に使うモデルを指定します。
ListViewの作成に必要なのは基本的にこのmodel
の指定だけですが、ほかの細かい所も属性やメソッドを設定することで設定可能です。
ListViewはテンプレートファイルを描画しますが、このテンプレートファイルについては開発者が独自で作成する必要があります。
そのときにコンテキスト内の変数を使う必要がありますが、この変数はListViewが自動で定義しています。
これの詳細については後述します。
モデルの作成
今回はListViewの解説のためにモデルを作成します。
モデルはPerson
という人物を表すモデルを作ります。
このモデルには人物の名前を表すname
フィールドと、人物の年齢を表すage
フィールドを作っておきます。
コードは↓のようになります。
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
age = models.IntegerField()
このモデルをListViewに指定することでリスト表示用のビューを作成することが可能です。
オブジェクトの作成
モデルを作ったので、次にテスト用にデータベースにモデルを保存します。
今回はDjangoのシェルを使って保存を行います。
↓のようにmanage.py
を使ってDjangoのシェルを起動します。
python manage.py shell
次にシェル内で↓のコードを入力します。
from myapp.models import Person
Person.objects.create(name='Taro', age=20)
Person.objects.create(name='Hanako', age=18)
Person.objects.create(name='Kenji', age=28)
↑のコードをシェルで実行するとデータベースにオブジェクトが作成されます。
これでListViewを試す準備が整いました。
ListViewによるビューの作成
ではListViewによるビューの作成を行います。
myapp/views.py
などを編集して↓のようにコードを書きます。
from django.views.generic import ListView
from .models import Person
class PersonList(ListView):
model = Person
なんとこれだけでビューができます。
1つ1つ見ていきます。
まず↓のようにしてListViewをdjango.views.generic
モジュールからインポートします。
from django.views.generic import ListView
余談ですがdjango.views.generic
にはListViewのほかにもいろいろなビューがあります。
次に↓のようにして先ほど作成したモデル(Person
)をインポートします。
from .models import Person
そして↓のようにPersonList
というビューを作ります。これはご覧の通りクラスです。
class PersonList(ListView):
model = Person
PersonList
はインポートしたListView
を継承するようにします。
こうすることでListView
の持つ機能を使えるようにしています。
そしてクラスの属性model
にPerson
モデルを入れます。
これでこのビューは機能します。
機能しますが、ほかにもやることはあります。
それはurls.py
の編集とテンプレートファイルの作成です。
urls.pyの編集
プロジェクトのurls.py
を↓のように編集します。
from django.contrib import admin
from django.urls import path
from myapp import views
urlpatterns = [
path('admin/', admin.site.urls),
path('persons/list/', views.PersonList.as_view()),
]
PersonList
クラスはas_view()
というメソッドを持っています。
これを呼び出すことでpath()
に設定できるビューを取得できます。
今回はpersons/list/
というパスにビューを設定します。
テンプレートファイルの作成
さきほど作成したPersonList
にはテンプレートファイルの所在の記述がありませんでした。
ListViewはデフォルトで「アプリ名/ビュー名.html
」の場所のテンプレートファイルを読み込みます。
たとえば今回はアプリ名はmyapp
でビュー名はPersonList
なので、「myapp/person_list.html
」というパスに解決されます。
これはmyapp/templates/myapp/person_list.html
のことです。
つまりここにテンプレートファイルを作ればPersonList
ビューが勝手に読み込んでくれるということになります。
person_list.html
を↓のようにして作成します。
<ul>
{% for person in object_list %}
<li>Name: {{ person.name }}, Age: {{ person.age }}</li>
{% endfor %}
</ul>
ListViewはデフォルトでオブジェクトのリストをコンテキスト内のobject_list
という変数に保存しています。
そのため↑のようにfor
文などでobject_list
を参照すると、オブジェクトの一覧を出力することが出来ます。
開発用サーバーで起動し、/persons/list/
にアクセスすると↓のような画面になります。
その他のListViewの機能
ListViewには他にも↓のような機能があります。
object_listを別の名前に変更する
テンプレートファイル内で参照するobject_list
という変数名を変更したい場合はビューを↓のように変更します。
from django.views.generic import ListView
from .models import Person
class PersonList(ListView):
model = Person
context_object_name = 'my_cute_persons'
context_object_name
属性に変数名を指定すると、object_list
がその変数名になります。
↑のビューでは↓のようにテンプレートを書くことが出来ます。
<ul>
{% for person in my_cute_persons %}
<li>Name: {{ person.name }}, Age: {{ person.age }}</li>
{% endfor %}
</ul>
コンテキストを拡張する
ビューにget_context_data()
メソッドを定義するとコンテキストの拡張などを行うことが出来ます。
from django.views.generic import ListView
from .models import Person
class PersonList(ListView):
model = Person
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['taro'] = Person.objects.filter(name='Taro').first()
return context
get_context_data()
内で親クラスのget_context_data()
を呼び出し、コンテキストを取得します。
あとはそのコンテキストに自由に変数を入れることが出来ます。
↑の例ではname
がTaro
のPerson
オブジェクトを入れています。
return context
でコンテキストを返すのを忘れないようにします。
クエリセットを指定する
ListViewの属性queryset
にクエリーセットを設定することで、ビューはそのクエリセットを使用するようになります。
from django.views.generic import ListView
from .models import Person
class PersonList(ListView):
model = Person
queryset = Person.objects.order_by('-name')
↑の場合、PersonList
は-name
で整列したオブジェクトのリストをビューに渡します。
動的にクエリセットを得る
メソッドget_queryset()
を定義することで動的にクエリセットを指定することが出来ます。
from django.views.generic import ListView
from .models import Person
class PersonList(ListView):
model = Person
def get_queryset(self):
return Person.objects.filter(name='Taro').order_by('-age').all()
属性queryset
の指定ではfor
文などは回しづらかったですが、↑のようにメソッド内であれば自由に設定できます。
テンプレートファイルを指定する
ListViewの属性template_name
にテンプレートファイルのパスを指定することで、テンプレートファイルを独自に設定できます。
from django.views.generic import ListView
from .models import Person
class PersonList(ListView):
model = Person
template_name = 'myapp/my_list.html'
おわりに
ListViewを使うとオブジェクトの一覧を表示する労力を減らすことが出来ます。
Djangoにはこの他にもさまざまな汎用ビューがあります。
これらを使うことで開発効率を上げることが出来るでしょう。
🦝 < わーい、〇うめうDjango大好き!
🐭 < ・・・・・・
🦊 < ・・・・・・