Record / Server Side
Django 処理の理解と初期画面のカスタマイズ
学習メモです。DjangoフレームワークにおけるHTTPリクエストの処理フロー。WSGIを通じたリクエストの受信から、URLconfによるルーティング、viewでのビジネスロジック実行などDjango内部の動き。PythonのWebアプリケーション開発における基礎知識として、モジュール検索パスやDRFの役割。
Django, Python 基礎
WSGI「ウィズギー」
Web Server Gateway Interfaceの略で、PythonのWebサーバーとWebアプリケーションをつなぐための標準的な共通ルール(インターフェース)です。
この規格のおかげで、Webサーバーを変更してもアプリケーションのコードを書き直す必要がなく、フレームワークの選択肢が広がります。
Pythonのインポートパス形式(モジュール検索パス)
myproject.wsgi:application
→myproject ディレクトリー(プロジェクト)にあるwsgi.pyファイル(モジュール)の中に記述されているapplicationオブジェクト
URLの設定はurls.pyファイル
settings.ROOT_URLCONF
→settings.py ファイルの ROOT_URLCONF
settings.py には下記のように記述されています
ROOT_URLCONF = 'myproject.urls’
myproject.urls
→myprojectディレクトリーのurls.py
→→URLの設定はurls.pyファイル
DRF
DRFはDjango REST Frameworkの略で、Django上でRESTfulなWeb APIを効率的に構築するための強力な拡張機能(フレームワーク)です。通常のDjangoが主にHTMLページを返すWebアプリケーションを構築するのに対し、DRFは主にJSONやXMLといったデータを返すAPIを構築するために特化しています。
Django の中の処理
- WSGI がリクエストを受け取る
- URLconf でどの view に行くか特定
- Middleware(前半)request をラップ(セッション、認証、CSRF、権限など)
- view にて、DB / データ処理 / 外部 API を呼ぶ。そして、テンプレートレンダリングまたは JSON 生成
- Middleware(後半)response をラップ(ヘッダ追加、圧縮など)
- WSGI 経由でレスポンスを返す
【1】WSGI がリクエストを受け取る
- Gunicorn が HTTP リクエストを受信
- WSGI 仕様に沿って、environ(ヘッダ等を詰めた dict)と start_response を用意
- application(environ, start_response) を呼び出す
ここから Django の世界に入ります。
【2】URLconf でどの view に行くか特定
application の裏側では、概ねこんなことをしています。
- settings.ROOT_URLCONF を読み込む(例: myproject.urls)
- urlpatterns のリストを上から順番にマッチング
- 最初にマッチしたパターンに対応する view 関数 / クラスベースビューを特定
- その view に渡す引数(/post/123/ の 123 など)を URL パターンから抽出
イメージ:
# myproject/[urls.py](http://urls.py)
urlpatterns = [
path("admin/", admin.site.urls),
path("blog/<int:pk>/", views.post_detail, name="post_detail"),
]/blog/5/ へのリクエストなら、views.post_detail(request, pk=5) が呼ばれます。
【3】Middleware(前半)request をラップ(セッション、認証、CSRF、権限など)
Django では、view が実行される前後を Middleware で囲んで処理しています。
MIDDLEWARE に定義した順番で、以下のようなことが行われます。
- セッションの読み書き(SessionMiddleware)
- 認証情報の設定(AuthenticationMiddleware)
- CSRF チェック(CsrfViewMiddleware)
- ロケール / タイムゾーン設定
- セキュリティヘッダの付与 など
相当の処理を行い、必要ならここで
- リダイレクトを返す
- 403/404 などを返す
こともあります(つまり view に到達する前にレスポンスが確定する場合もあります)。
【4】view にて、DB / データ処理 / 外部 API を呼ぶ。そして、テンプレートレンダリングまたは JSON 生成
URLconf と Middleware を通過したら、いよいよ view 本体が動きます。
- request.user を見て認証・権限チェック
- models を通じて DB 参照・更新
- 必要があれば外部 API にリクエスト
- HTML を返すなら render() でテンプレートレンダリング。API なら JSON を組み立てて JsonResponse / DRF の Response を返す
- HttpResponse オブジェクトを返す
例(HTML を返す view):
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, "blog/post_detail.html", {"post": post})例(API 用 view / DRF):
from rest_framework.decorators import api_view
from rest_framework.response import Response
@api_view(["GET"])
def api_status(request):
data = {"status": "ok"}
return Response(data)この HttpResponse / Response オブジェクトが、次のステップに進みます。
【5】Middleware(後半)response をラップ(ヘッダ追加、圧縮など)
view からレスポンスが返ってきたあと、後半の Middleware が順番にレスポンスを通していきます。
- レスポンスヘッダの追加
- Cookie のセット
- 圧縮(GZip)
- エラーハンドリング(500 ページ差し替え など)
などがここで行われます。
【6】WSGI 経由でレスポンスを返す
最終的に Django が HttpResponse を WSGI 経由で Gunicorn に返す
Django初期画面のカスタマイズ
Django をインストールすると下記画面が表示されます、初期画面です。これを元にもろもろ開発していきます。
- アプリケーション作成:
python manage.py startapp myapp - settings.pyにmyappを追加
- myapp/views.pyにビュー関数を作成
- myapp/urls.pyを作成してURLパターンを定義
- myproject/urls.pyでmyapp.urlsをインクルード
- templates/myapp/home.htmlを作成
- 開発サーバーを起動:
python manage.py runserver
アプリケーション(myapp)の作成
Djangoではプロジェクト(myproject)とアプリケーション(myapp)を分けて管理します。プロジェクトは設定の容器で、アプリケーションは実際の機能を実装する場所です。
仮想環境立ち上げて実行
source venv/bin/activate
# プロンプトが (venv) で始まるようになります
# 仮想環境を止める場合
deactivate# /var/www/django-5 ディレにて
python manage.py startapp myapp作成後のディレクトリ構造:
django-5/
├── myproject/
│ ├── settings.py // (1)
│ ├── urls.py // (3)
│ └── wsgi.py
└── myapp/
├── migrations/
├── __init__.py
├── admin.py
├── apps.py
├── models.py
├── tests.py
├── urls.py // (4)新規作成
└── views.py // (2)更新が必要なファイルと手順
(1)myproject/settings.py
作成したアプリケーションを登録:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp', # 追加
](2)myapp/views.py
カスタム画面を表示するビューを作成:
from django.shortcuts import render
from django.http import HttpResponse
def home(request):
return render(request, 'myapp/home.html')
def about(request):
return render(request, 'myapp/about.html')
# または、シンプルなHTMLレスポンス
def simple_home(request):
return HttpResponse('<h1>カスタム初期画面</h1>')(3)myproject/urls.py
URLパターンを設定:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('myapp.urls')), # ルートURLをmyappに接続
](4)myapp/urls.py(新規作成)
アプリケーション内のURL設定:
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'), # https://django-5.usual.tools/
path('about/', views.about, name='about'),
](5)テンプレートファイルの作成
ディレクトリ構造:
myapp/
└── templates/
└── myapp/
└── home.htmlmyapp/templates/myapp/home.html:
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>カスタム初期画面</title>
</head>
<body>
<h1>Django カスタム画面へようこそ</h1>
<p>これはカスタマイズされた初期画面です。</p>
</body>
</html>Djangoのテンプレート継承(Layout機能)
ベースとなる共通のHTML構造(ヘッダー、フッター、ナビゲーションなど)を定義した親テンプレートを作成し、子テンプレートでその構造を再利用しつつ、ページ固有の部分だけを{% extends %}タグと{% block %}タグを使って上書き・拡張する仕組みです。これにより、コードの重複を減らし、保守性を高め、DRY原則(Don't Repeat Yourself)を実現します。
1. ベーステンプレート(base.html)の作成
サイト共通のレイアウトを定義します:
<!-- myapp/templates/myapp/base.html -->
{% load static %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}デフォルトタイトル{% endblock %}</title>
<!-- 共通のCSS -->
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<!-- ページ固有のCSS -->
{% block extra_css %}{% endblock %}
</head>
<body>
<header>
<nav>
<!-- 共通ナビゲーション -->
<a href="{% url 'home' %}">ホーム</a>
<a href="{% url 'about' %}">About</a>
</nav>
</header>
<main>
{% block content %}
<!-- ここに各ページの内容が入る -->
{% endblock %}
</main>
<footer>
<p>© 2026 My Django Site</p>
</footer>
<!-- 共通のJavaScript -->
<script src="{% static 'js/script.js' %}"></script>
<!-- ページ固有のJavaScript -->
{% block extra_js %}{% endblock %}
</body>
</html>2. 子テンプレートでの継承
各ページでbase.htmlを継承して使用します:
<!-- myapp/templates/myapp/home.html -->
{% extends 'myapp/base.html' %}
{% block title %}ホームページ{% endblock %}
{% block extra_css %}
<style>
.home-specific {
color: blue;
}
</style>
{% endblock %}
{% block content %}
<h1>Django カスタム画面へようこそ</h1>
<p>これはカスタマイズされた初期画面です。</p>
{% endblock %}
{% block extra_js %}
<script>
console.log('ホームページ固有のスクリプト');
</script>
{% endblock %}テンプレート継承の主要な機能
{% extends 'base.html' %}ベーステンプレートを継承{% block block_name %}...{% endblock %}上書き可能なブロックを定義{{ block.super }}親テンプレートの内容を保持しつつ追加{% include 'partial.html' %}部分テンプレートの読み込み
複数レイアウトの使い分け
用途に応じて複数のベーステンプレートを作成できます:
myapp/templates/myapp/
├── base.html # メインレイアウト
├── base_admin.html # 管理画面用レイアウト
├── base_simple.html # シンプルなレイアウト
├── home.html
└── about.html部分テンプレート(Partial)の活用
共通パーツを別ファイルに分離:
<!-- myapp/templates/myapp/includes/header.html -->
<header>
<nav>
<a href="{% url 'home' %}">ホーム</a>
</nav>
</header>
<!-- base.htmlで使用 -->
{% include 'myapp/includes/header.html' %}画面が変わらない場合はgunicorn再起動
# サービスの起動
sudo systemctl daemon-reload
sudo systemctl start gunicorn-django5
sudo systemctl enable gunicorn-django5
sudo systemctl status gunicorn-django5
# サービスの停止
sudo systemctl stop gunicorn-django5
# サービスの再起動
sudo systemctl restart gunicorn-django5