ユーニックス総合研究所

  • home
  • archives
  • django-list-view

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というアプリケーション内にビューを作っていきます。
このmyapppython 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の持つ機能を使えるようにしています。
そしてクラスの属性modelPersonモデルを入れます。

これでこのビューは機能します。
機能しますが、ほかにもやることはあります。
それは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()を呼び出し、コンテキストを取得します。
あとはそのコンテキストに自由に変数を入れることが出来ます。
↑の例ではnameTaroPersonオブジェクトを入れています。
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大好き!

🐭 < ・・・・・・

🦊 < ・・・・・・

関連記事

参考