Django における共通テンプレート設計と継承機制の実装

Web アプリケーション開発において、ヘッダー、フッター、ナビゲーションバーなどの共通要素を各ページごとに記述することは非効率的であり、保守性を低下させます。Django のテンプレートシステムでは、テンプレート継承という機能を提供しており、これにより共通の骨格を定義し、個々のページで必要な部分のみをオーバーライドする開発手法が可能になります。

一般的に、プロジェクトのルートテンプレートディレクトリに base.html という名前のファイルを作成し、ここにサイト全体の共通構造を記述します。このファイル内では、変更可能な箇所を block タグで囲み、子テンプレートからこれらのブロックを拡張または置換できるようにします。

以下は、Bootstrap フレームワークを利用した基本的なベーステンプレートの構成例です。ここでは、ページタイトル、追加の CSS、メインコンテンツ、追加の JavaScript をそれぞれ独立したブロックとして定義しています。

<{% load static %}>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block page_title %}Default Title{% endblock %}</title>
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    {% block css_imports %}{% endblock %}
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container">
        <a class="navbar-brand" href="{% url 'dashboard' %}">TechHub</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navMenu">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navMenu">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item"><a class="nav-link" href="{% url 'dashboard' %}">ダッシュボード</a></li>
                <li class="nav-item"><a class="nav-link" href="{% url 'staff' %}">スタッフ一覧</a></li>
            </ul>
            <ul class="navbar-nav">
                <li class="nav-item"><a class="nav-link" href="{% url 'logout' %}">ログアウト</a></li>
            </ul>
        </div>
    </div>
</nav>

<div class="container mt-4">
    {% block main_area %}{% endblock %}
</div>

<script src="{% static 'js/jquery.min.js' %}"></script>
<script src="{% static 'js/bootstrap.bundle.min.js' %}"></script>
{% block js_imports %}{% endblock %}
</body>
</html>

このベーステンプレートを利用する際、子テンプレートでは extends ディレクティブを使用して親テンプレートを指定し、定義されたブロック内に固有のコンテンツを記述します。これにより、ナビゲーションやフッターのコードを重複させることなく、ページ固有の情報を表示できます。

例えば、ダッシュボードページ用のテンプレートは以下のようになります。

{% extends 'base.html' %}

{% block page_title %}ダッシュボード - TechHub{% endblock %}

{% block main_area %}
<h1>ようこそ、管理者様</h1>
<p>这里是システム管理画面的主要内容区域です。</p>
<div class="card">
    <div class="card-body">
        <h5 class="card-title">ステータス</h5>
        <p class="card-text">システムは正常に稼働しています。</p>
    </div>
</div>
{% endblock %}

同様に、スタッフ一覧ページなど他のページでも同じ構造を共有できます。テンプレート継承を活用することで、サイト全体のデザイン変更が必要な際にも、ベーステンプレートのみを修正すれば全体に反映されるため、メンテナンスコストを大幅に削減できます。

次に、これらのテンプレートをレンダリングするための URL 設定とビュー関数の実装例を示します。URL conf では、各パスに対応するビュー関数を登録し、名前付き URL を定義することでテンプレート内のリンク管理を容易にします。

from django.urls import path
from . import views

urlpatterns = [
    path('', views.landing, name='landing'),
    path('dashboard/', views.dashboard, name='dashboard'),
    path('info/', views.info, name='info'),
    path('staff/', views.staff_list, name='staff'),
]

ビュー側では、必要なデータをコンテキストとしてテンプレートに渡します。ユーザー管理機能を含むプロジェクトでは、認証モデルからデータを取得し、表示用のコンテキスト辞書に格納してレスポンスを生成します。

from django.contrib.auth.models import User
from django.shortcuts import render
from django.http import HttpResponse

def landing(request):
    return HttpResponse("Welcome to the root page.")

def dashboard(request):
    return render(request, 'dashboard.html')

def info(request):
    return render(request, 'info.html')

def staff_list(request):
    members = User.objects.all()
    context = {
        'page_title': 'スタッフ一覧',
        'member_list': members
    }
    return render(request, 'app/staff_list.html', context)

タグ: Django template-inheritance bootstrap-4 python-web

7月30日 04:53 投稿