こんにちは、DXCEL WAVEの運営者(@dxcelwave)です!
DetaiViewとは?
DetailViewはデータベースとの容易な情報連携を実現できるクラスベースビューです。上図(右)のように、あるテーブルの単一レコードを用いた詳細画面を作成する際に広く用いられます。
また、DetailViewは上図(左)のような一覧画面を作成する際に用いるListViewとしばしセットで用いられます。ListViewの基本操作は下記の記事にて紹介していまゆえ、是非ご覧ください。
【Django】ListView(リストビュー)の基本操作入門|PythonによるWebアプリ開発#14
データベース連携の際に便利なDjangoのクラスベースビューの1つ「ListView」の紹介記事です。「ListViewとは何か?」「ListViewで何ができるのか?」「どのようにプログラミングするのか?」 本記事ではこのような疑問にお応えします。
クラスベースビューの基本概要を知りたい方はこちらの記事もご覧ください。
【Django】クラスベースビュー基本操作入門|PythonによるWebアプリ開発#12
クラスベースビュー(Class Based View)の概要説明した記事です。 「そもそもクラスベースビューとは何か?」「ビュークラスとビュー関数の記述方法の違いは?」「代表的なクラスベースビューではどんなことができる?」このような疑問にお応えします。
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
モデルクラス作成後はマイグレーションを行い、データベースに適用しましょう。マイグレーション方法は下記の記事で紹介しています。
【Django】モデルの操作・データベース作成・削除|PythonによるWebアプリ開発(models.py)#6
Djangoのモデルの構築方法を詳しく紹介します。モデルとは何か?という観点から、モデル構築手順に至るまで知ることができます。また、モデルからデータベースにテーブル登録した後の不具合対応として、データベースの削除方法にも言及します。
管理画面:レコードを登録
データベースに適用したCompanyとEmployeeテーブル内にレコードを追加します。
Companyテーブル
Employeeテーブル
管理画面からレコード追加する方法は下記で紹介しています。適時ご参照ください。
【Django】管理画面からデータベース操作・スーパーユーザー登録|PythonでWebアプリ開発(admin)#7
この記事は、Djangoフレームワークを活用するモデルの活用方法について触れます。特に、Djangoの管理ツールにモデルクラスを登録および管理ユーザーを登録、管理画面上でデータベースのテーブルを閲覧・レコード追加できるに至るまでを詳しく解説します。
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>
- views.context_object_nameで定めたcompany_detailを指定
- Employees(models.pyのrelated_name=’Employees’部分)を指定し、Employeeテーブルと外部キーで連携
- allと指定し、for文を記載することでレコードを全て表示
これでWebアプリは完成です!最後にローカルサーバーを開き画面が表示できるか確認してみましょう。
【参考】Djangoの解説記事一覧
最後までご覧いただきありがとうございました。当サイトではDjangoフレームワークを用いた解説記事を多数取り扱っております。次のように体系的に整理しておりますため学習にお役立て下さい。
Django学習に最適!
当サイトが運営するDjango記事一覧
【参考】Pythonでできること・お仕事探し
最後に
お問い合わせフォーム
上記課題に向けてご気軽にご相談下さい。
お問い合わせはこちら