ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
Django Template の全体像
Django Template Language (DTL) は Django 標準のテンプレートエンジン。HTML に {% tag %} や {{ variable }} を埋め込み、ビューから渡されたコンテキストで描画します。Jinja2 も切り替え可能ですが、DTL がデフォルトで完備されているので本記事は DTL を扱います。
ステップ 1: settings.py の TEMPLATES 設定
プロジェクト作成時にデフォルトで生成されていますが、DIRS を埋めるのが最初の作業です:
# mysite/settings.py
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # ← プロジェクト共通テンプレ
'APP_DIRS': True, # ← 各アプリの templates/ も探索
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
| 設定キー | 役割 |
|---|---|
| BACKEND | テンプレートエンジン本体(DTL or Jinja2) |
| DIRS | 共通テンプレディレクトリ(リスト順に探索) |
| APP_DIRS | True で <app>/templates/ を自動探索 |
| context_processors | 全テンプレに自動注入する変数群 |
ステップ 2: ディレクトリ構成
mysite/
├── manage.py
├── mysite/
│ ├── settings.py
│ └── urls.py
├── templates/ ← BASE_DIR / 'templates'(共通)
│ ├── base.html
│ └── partials/
│ ├── header.html
│ └── footer.html
└── blog/ ← アプリ
├── views.py
└── templates/ ← APP_DIRS で自動探索
└── blog/ ← ★名前衝突回避のためアプリ名でネスト
├── index.html
└── detail.html
重要: アプリの templates ディレクトリは blog/templates/blog/ のようにアプリ名でネストするのが慣例。複数アプリで index.html が衝突するのを防ぎます。
ステップ 3: ビューからテンプレートを呼ぶ
# blog/views.py
from django.shortcuts import render
def index(request):
context = {
'posts': Post.objects.all(),
'site_name': 'My Blog',
}
return render(request, 'blog/index.html', context)
# ↑ APP_DIRS により blog/templates/blog/index.html を解決
DTL の基本文法
変数表示 {{ ... }}
<p>{{ post.title }}</p>
<p>{{ user.username }}</p>
<p>{{ posts.0.title }}</p> {# リストのインデックス #}
<p>{{ post.created_at|date:"Y-m-d" }}</p> {# フィルター適用 #}
タグ {% ... %}
{% if user.is_authenticated %}
<p>こんにちは {{ user.username }} さん</p>
{% else %}
<a href="{% url 'login' %}">ログイン</a>
{% endif %}
{% for post in posts %}
<li>{{ post.title }} ({{ forloop.counter }}/{{ posts|length }})</li>
{% empty %}
<li>記事はまだありません</li>
{% endfor %}
{% url 'blog:detail' post.pk %} {# URL 解決 #}
{% csrf_token %} {# CSRF トークン #}
{% load humanize %} {# テンプレタグライブラリ読込 #}
主要フィルター一覧
| フィルター | 例 | 結果 |
|---|---|---|
date | {{ d|date:"Y-m-d H:i" }} | 2026-06-10 12:34 |
length | {{ list|length }} | 要素数 |
default | {{ name|default:"匿名" }} | 空なら "匿名" |
truncatechars | {{ body|truncatechars:50 }} | 50文字 + ... |
safe | {{ html|safe }} | エスケープ無効化(★危険、入力検証必須) |
linebreaks | {{ body|linebreaks }} | 改行を <br> / <p> に |
floatformat | {{ price|floatformat:2 }} | 1234.50 |
upper / lower | {{ s|upper }} | 大文字化 |
テンプレート継承 (extends / block)
共通レイアウトを base.html に定義し、各ページで上書きします:
{# templates/base.html #}
{% load static %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{% block title %}{{ site_name }}{% endblock %}</title>
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
{% include 'partials/header.html' %}
<main>
{% block content %}{% endblock %}
</main>
{% include 'partials/footer.html' %}
</body>
</html>{# blog/templates/blog/index.html #}
{% extends 'base.html' %}
{% block title %}記事一覧 | {{ block.super }}{% endblock %}
{% block content %}
<h1>記事一覧</h1>
<ul>
{% for post in posts %}
<li><a href="{% url 'blog:detail' post.pk %}">{{ post.title }}</a></li>
{% endfor %}
</ul>
{% endblock %}
include で部品化
{# 引数渡し #}
{% include 'partials/card.html' with post=post show_author=True %}
{# 親のコンテキスト引き継がない(独立) #}
{% include 'partials/card.html' with post=post only %}
{% load static %} と静的ファイル
{% load static %}
<link rel="stylesheet" href="{% static 'blog/css/post.css' %}">
<img src="{% static 'blog/img/logo.png' %}" alt="logo">
<script src="{% static 'blog/js/main.js' %}"></script># settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / 'static'] # 開発時の追加探索パス
STATIC_ROOT = BASE_DIR / 'staticfiles' # collectstatic の出力先(本番)
テンプレートのキャッシュ(本番)
# settings.py(本番のみ。DEBUG=True ならコメントアウト)
TEMPLATES = [
{
# ...
'APP_DIRS': False, # cached.Loader 使用時は False
'OPTIONS': {
'loaders': [
('django.template.loaders.cached.Loader', [
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
]),
],
'context_processors': [...],
},
},
]
FAQ
Q: テンプレートが見つからないと言われる
A: blog/templates/blog/index.html のようにアプリ名でネストしているか確認。また INSTALLED_APPS に登録され APP_DIRS: True である必要があります。
Q: Jinja2 を使いたい
A: TEMPLATES に BACKEND: 'django.template.backends.jinja2.Jinja2' を追加。DTL と並行利用も可。
Q: テンプレートで Python 関数を直接呼びたい
A: 不可(意図的制限)。カスタムテンプレートタグ / フィルターを templatetags/ に作って {% load %} して使います。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 Spring Frameworkのアノテーション一覧
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- PHPでのファイルアップロード方法|multipart/form-dataと$_FILES 2026-08-07 17:15:57
- PHP $_SERVERとは|DOCUMENT_ROOT・PHP_SELFなど主な要素 2026-08-07 17:15:57
- Scratchのアカウントの作り方|メールアドレスとユーザー名の登録手順 2026-08-07 17:15:57
- djangoにおけるMVCアプリケーション実装例 2026-08-07 17:15:57
- Bluetoothとは|仕組み・BLEとClassicの違い・用途 2026-08-07 17:15:57
- Spring Bootのテスト入門|@SpringBootTestとJUnitでの単体・結合テスト 2026-08-07 17:15:57
- Java とは?言語仕様・JVM・主要フレームワーク一覧 2026-08-07 17:15:56
- インストール方法(Windows版) 2026-08-07 17:15:56
- APIキー取得方法 2026-08-07 17:15:56
- 【PHPフレームワーク】Laravelの使い方 2026-08-07 17:15:56
- Scratch 作品の公開方法 2026-08-07 17:15:56
- Google OAuth 2.0 認証の実装方法 2026-08-07 17:15:56
- データベースとは?RDB / NoSQL / SQL の基礎 2026-08-07 17:15:56
- インストール(eclipseプラグイン) 2026-08-07 17:15:56
- Spring Frameworkの使い方 2026-08-07 17:15:56
コメントを削除してもよろしいでしょうか?