【Django】ListView(リストビュー)の基本操作入門|PythonによるWebアプリ開発#14

こんにちは、DXCEL WAVEの運営者(@dxcelwave)です!

データベースの情報連携を行う際に利用すると便利なDjangoのクラスベースビューの1つ「ListView」の紹介記事です。「ListViewとは何か?」「ListViewで何ができるのか?」「どのようにプログラミングするのか?」
本記事ではこのような疑問にお応えします。

目次

リストビュー(List View)とは?

ListViewはDjangoに用意されたクラスベースビューの1つであり、データベースの情報を画面上で容易に反映・操作できる便利なビューです。図のように、ある特定情報の一覧覧画面を作成する際によく用いられます。

クラスベースビューの基本概要は下記で紹介しています。適時ご参照ください。

事前準備

それでは下記より実際にWebアプリを作成しながら、ListViewの操作に慣れていきましょう!まずは事前準備を行います。

ディレクトリ構成

上記のディレクトリ構成をもとに、以下ListViewの使い方を解説します。対象ファイルは下記であり、事前準備ではviews.py以外のファイルを作成することとします。

  • models.py
  • views.py
  • urls.py
  • Company_list.html
  • Header.html

models.py:テーブル作成

データベースに格納されたテーブル・レコード情報を一覧画面に表示することを目的に、models.pyにモデルクラスを記載します。モデルクラスをもとに、今回はCompanyというテーブルを作成します。

from django.db import models

class Company(models.Model):
    name      = models.CharField(max_length=256)
    industory = models.CharField(max_length=256)
    location  = models.CharField(max_length=256)

    def __str__(self):
        return self.name

モデルクラス作成後はマイグレーションを行い、データベースにテーブル情報を反映しましょう。マイグレーションの方法は下記の記事で紹介しています。

管理画面:レコードを登録

上記で作成したCompanyテーブル内にレコードを幾つか追加しましょう。管理(admin)画面からレコードを追加する方法は下記の記事で紹介していますので、適時ご参照ください。

表示設定:urls.py

urls.pyの表示設定を行います。本記事で下記の仕様でURLマッピングを行います。

  • アプリケーションフォルダ内にurls.pyを新規作成
  • urls.py(プロジェクトフォルダ)の情報をurls.py(アプリケーションフォルダ)に紐付け
  • urls.py(アプリケーションフォルダ)をメインの編集ファイルとして利用

以下それぞれのファイルにコードを記載しましょう。

プロジェクトフォルダ内のurls.py

from django.contrib import admin
from django.urls import path
from django.urls import include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('App_Folder.urls')),   #(App_Folder)はご自身で作成したアプリケーションフォルダがあればその名前を記載
]

アプリケーションフォルダ内のurls.py

from django.urls import path
from . import views

#アプリ名を定義
app_name = "App"

urlpatterns = [
    path('', views.CompanyList.as_view(), name='list'),
]

後ほど紹介するviews.pyにてCompanyListというクラスを作成します。そのため、上記urlpatternsではCompanyListを指定し、クラスベースビューを用いることを示すためにas_view()メソッドを記述します。

urls.pyの基本的な設定方法は下記の記事で紹介していまため、適時ご覧ください。

テンプレートファイル作成

テンプレートファイルは、ヘッダー情報を表示するHeader.htmlと、Companyテーブルのレコードを表示するCompany_list.htmlを作成します。今回CSSのデザインはbootstrap5を用いており、内容は割愛します。

Header.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    <title>ListView入門</title>

</head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <div class="navbar-nav">
        <!-- urls.pyで定義したアプリ名 + urlpatternのpathで定めたnameを指定し、リンクで遷移できるようにする -->
        <a class="navbar-brand" href="{% url 'App:list' %}">CompanyList</a>
      </div>
    </nav>

    <!-- Company_list.htmlのHTMLコンテンツを呼び出し -->
    <div class="container">
      {% block content_block %}
      {% endblock %}
    </div>

  </body>
</html>

上記の補足として、下記部分はurls.py(アプリケーションフォルダ)で実行したapp_name=”App”とpathメソッドの引数name=”list”で遷移先を指定しています。

<a class="navbar-brand" href="{% url 'App:list' %}">CompanyList</a>

Company_list.html

{% extends "Header.html" %}

{% block content_block %}

<h2>会社一覧</h2>
<table class="table">
  <thead>
    <tr><th>会社名</th></tr>
  </thead>
  <tbody>
    {% for company in company_list %}
    <tr><td>{{ company.name }}</td></tr>
    {% endfor %}
  </tbody>
</table>

{% endblock %}

Company_list.htmlのヘッダー情報は、{% extends Header.html %}および{% block %}というテンプレートタグを用いてHeader.htmlの情報を引き継いでいます。

データベースに作成したCompanyテーブルのレコード情報を一覧表示します。下記では「後にviews.pyで定義するオブジェクト(company_list)からmodels.pyのフィールド名(name)を指定し、for文で一覧表示する」処理を実行しています。

{% for company in company_list %}
<tr><td>{{ company.name }}</td></tr>
{% endfor %}

それでは下記よりviews.pyにてListViewクラスを記述しながら特徴を把握していきましょう!

【実践】テーブルのレコード情報を一覧表示

上図のような、事前準備したCompanyテーブルのレコード情報を一覧表示するWebアプリを作成します。views.pyを下記のように記載し、ローカルサーバーを起動してみましょう。

views.py

from django.views.generic import ListView
from . import models

class CompanyList(ListView):
    # Companyテーブル連携
    model = models.Company
    
    # レコード情報をテンプレートに渡すオブジェクト
    context_object_name = "company_list"
    
    # テンプレートファイル連携
    template_name = "Company_list.html"

ListViewを継承したビュークラスは、下記オブジェクトを活用して作成されています。

model モデルクラスを指定すると対象のデータベースのテーブルと連携する
context_object_name 指定したオブジェクト名をテンプレートに渡す
template_name 指定したテンプレートファイルをレンダリングする

ListViewを継承すると容易にデータベース連携できるが分かりますね!

【実践】レコード情報を並び替え・フィルタリングして表示

続いてテンプレート上に表示されたレコードを並び替え・フィルタリングして表示する場合を示します。下記を記載してローカルサーバーを起動し、画面を確認しましょう。

views.py

from django.views.generic import ListView
from . import models

class CompanyList(ListView):
    # Companyテーブル連携・表示設定
    queryset = models.Company.objects.filter(location="Tokyo").order_by("-name")

    # レコード情報をテンプレートに渡すオブジェクト
    context_object_name = "company_list"

    # テンプレートファイル連携
    template_name = "Company_list.html"

上記コードはmodelの代わりに、querysetでモデルクラスを指定するのが特徴です。

queryset 指定したモデルの表示設定(並び替え・フィルタリング)を行う際に利用

また、レコードを並び替えやフィルタリングは、下記のメソッドを用います。

filter(条件記載) フィルタリングする際に利用
order_by(条件記載) 並び替えする際に利用

【実践】条件分岐を用いてレコード情報を出し分け

クライアント側のアクションに基づき表示できる情報を変更したい場合、get_query_set()関数をオーバーライドして利用すると便利です。以下GETとPOST処理で挙動が異なるWebアプリを構築してみましょう。

views.py

from django.views.generic import ListView,DetailView
from . import models

class CompanyList(ListView):
    #Companyテーブル連携
    model = models.Company
    #レコード情報をテンプレートに渡すオブジェクト
    context_object_name = "company_list"
    #テンプレートファイル連携
    template_name = "Company_list.html"

    #条件分岐でレコード表示変更
    def get_queryset(self, **kwargs):
        #初期条件:レコードを全て表示(記載は任意)
        queryset = super().get_queryset(**kwargs)

        #Get処理
        if self.request.method == "GET":
            queryset = models.Company.objects.filter(location="Tokyo").order_by("-name")

        #Post処理
        elif self.request.mothod == "POST":
            queryset = models.Company.objects.filter(location="Osaka")
        return queryset

【実践】DetailViewと連携し、詳細画面を作成

テーブルのレコードを一覧表示するのに役立つListViewは、DetailViewというビュークラスと一緒に用いられることがよくあります。例えば、上図のように、ListViewで一覧画面、DetailViewで詳細画面の表示設定を行う場合です。

DetailViewの基本操作は下記の記事にて紹介しています。是非ご参照ください。

【参考】Djangoの解説記事一覧

最後までご覧いただきありがとうございました。当サイトではDjangoフレームワークを用いた解説記事を多数取り扱っております。次のように体系的に整理しておりますため学習にお役立て下さい。

Django学習に最適!

当サイトが運営するDjango記事一覧

【参考】Pythonでできること・お仕事探し

最後に

この記事が気に入ったら
フォローしてね!

本記事をシェア!
目次