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)