【Django】DetailViewの基本操作入門|PythonによるWebアプリ開発#15

当ページには広告が含まれています。

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

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

目次

DetaiViewとは?

DetailViewはデータベースとの容易な情報連携を実現できるクラスベースビューです。上図(右)のように、あるテーブルの単一レコードを用いた詳細画面を作成する際に広く用いられます。

また、DetailViewは上図(左)のような一覧画面を作成する際に用いるListViewとしばしセットで用いられます。ListViewの基本操作は下記の記事にて紹介していまゆえ、是非ご覧ください。

クラスベースビューの基本概要を知りたい方はこちらの記事もご覧ください。

DetailViewを用いたWebアプリ実装

本記事では上図のような会社情報一覧・詳細画面を持つWebアプリを実装する流れで、DetailViewの基本操作を詳しく解説していきます。

ディレクトリ構成

上記のディレクトリ構成をもとに、Webアプリを作成します。編集する対象ファイルは下記です。

ファイル名 用途
models.py DB連携・テーブル作成
urls.py 画面表示設定
views.py 画面表示設定
Company_list.html ListViewと連携し、会社一覧画面をデザイン
Company_detail.html DetailViewと連携し、会社詳細画面をデザイン
Header.html グローバルナビなど共通ヘッダー情報をデザイン

models.py:テーブル作成

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

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

#会社に紐づく従業員情報を格納するテーブル
class Employee(models.Model):
    name    = models.CharField(max_length=256)
    age     = models.PositiveIntegerField()
    company = models.ForeignKey(Company,related_name='Employees',on_delete=models.CASCADE)

    def __str__(self):
        return self.name

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

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

データベースに適用したCompanyとEmployeeテーブル内にレコードを追加します。

Companyテーブル

Employeeテーブル

管理画面からレコード追加する方法は下記で紹介しています。適時ご参照ください。

urls.py:表示設定

urls.pyを用いて表示設定を行います。本記事ではurls.pyを下記の仕様で設定します。

  • アプリケーションフォルダ内に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'),             #一覧画面
    path('detail/<int:pk>/',views.CompanyDetail.as_view(),name='detail'),  #詳細画面
]

詳細画面のURLは、Companyテーブルのレコードの主キーをもとに振り分けされる設定としています。

views.py:画面表示

views.pyにListViewとDetailViewを用いたクラスベースビューを記述します。

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"


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

各クラスベースビューは、下記の役割を有するオブジェクトを活用しています。

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

このようにクラスベースビューを活用するとシンプルに表示設定できるのが特徴です。

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

最後にテンプレートファイルを作成します。ファイルは下記3つを作成します。今回CSSのデザインはbootstrap5を用いており、内容は割愛します。

ファイル名 用途
Header.html グローバルナビなど共通ヘッダー情報をデザイン
Company_list.html ListViewと連携し、会社一覧画面をデザイン
Company_detail.html DetailViewと連携し、会社詳細画面をデザイン

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>

{% url ‘App:list’ %}というテンプレートタグは、urls.py(アプリケーション)で記述したapp_name=”App”とpathメソッドの引数name=”list”で遷移先を指定しています。

Company_list.html

{% extends "Header.html" %}

{% block content_block %}

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

{% endblock %}

詳細画面へのリンク先は下記のようにID(主キー)を指定することで、urls.pyと平仄を合わせています。

<td><a href="detail/{{ company.id }}">詳細</a></td>

Company_Detail.html

{% extends "Header.html" %}

{% block content_block %}
<div class="jumbotron">
  <h2>会社詳細</h2>
  <table class="table">
    <thead>
      <tr>
        <th scope="col">会社名</th>
        <th scope="col">業界</th>
        <th scope="col">地域</th>
    </tr>
  </thead>
    <tbody>
      <tr>
        <td>{{ company_detail.name }}</td>
        <td>{{ company_detail.industory }}</td>
        <td>{{ company_detail.location }}</td>
      </tr>
    <tbody>
  </table>


  <h2>従業員</h2>
<table class="table">
  <thead>
    <tr>
      <th scope="col">名前</th>
      <th scope="col">年齢</th>
  </tr>
</thead>
  <tbody>
      {% for employee in company_detail.Employees.all %}
      <tr>
        <td>{{ employee.name }}</td>
        <td>{{ employee.age }}</td>
      </tr>
      {% endfor %}
  <tbody>
</table>

{% endblock %}

上記テンプレートをもとに、Companyテーブルの1レコードを詳細表示します。

DetailViewを用いたビュークラスにおいて、下記はcontext_object_nameで指定したオブジェクトを渡しています。

<td>{{ company_detail.name }}</td>
<td>{{ company_detail.industory }}</td>
<td>{{ company_detail.location }}</td>

続いて下記のコードは、以下のような条件に基づき処理を実行しています。

  <tbody>
      {% for employee in company_detail.Employees.all %}
      <tr>
        <td>{{ employee.name }}</td>
        <td>{{ employee.age }}</td>
      </tr>
      {% endfor %}
  <tbody>
  1. views.context_object_nameで定めたcompany_detailを指定
  2. Employees(models.pyのrelated_name=’Employees’部分)を指定し、Employeeテーブルと外部キーで連携
  3. allと指定し、for文を記載することでレコードを全て表示

これでWebアプリは完成です!最後にローカルサーバーを開き画面が表示できるか確認してみましょう。

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

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

Django学習に最適!

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

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

最後に

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

目次