Django 処理の理解と初期画面のカスタマイズ
#プログラミング

created: 2026/01/01, modified: 2026/01/01

標準のサムネイル 2024-06

学習メモです。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 の中の処理

  1. WSGI がリクエストを受け取る
  2. URLconf でどの view に行くか特定
  3. Middleware(前半)request をラップ(セッション、認証、CSRF、権限など)
  4. view にて、DB / データ処理 / 外部 API を呼ぶ。そして、テンプレートレンダリングまたは JSON 生成
  5. Middleware(後半)response をラップ(ヘッダ追加、圧縮など)
  6. WSGI 経由でレスポンスを返す

【1】WSGI がリクエストを受け取る

  1. Gunicorn が HTTP リクエストを受信
  2. WSGI 仕様に沿って、environ(ヘッダ等を詰めた dict)と start_response を用意
  3. application(environ, start_response) を呼び出す

ここから Django の世界に入ります。

【2】URLconf でどの view に行くか特定

application の裏側では、概ねこんなことをしています。

  1. settings.ROOT_URLCONF を読み込む(例: myproject.urls)
  2. urlpatterns のリストを上から順番にマッチング
  3. 最初にマッチしたパターンに対応する view 関数 / クラスベースビューを特定
  4. その 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](http://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 本体が動きます。

  1. request.user を見て認証・権限チェック
  2. models を通じて DB 参照・更新
  3. 必要があれば外部 API にリクエスト
  4. HTML を返すなら render() でテンプレートレンダリング。API なら JSON を組み立てて JsonResponse / DRF の Response を返す
  5. 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 をインストールすると下記画面が表示されます、初期画面です。これを元にもろもろ開発していきます。

DjangoでWebサイト、初開設
  1. アプリケーション作成:`python manage.py startapp myapp`
  2. settings.pyにmyappを追加
  3. myapp/views.pyにビュー関数を作成
  4. myapp/urls.pyを作成してURLパターンを定義
  5. myproject/urls.pyでmyapp.urlsをインクルード
  6. templates/myapp/home.htmlを作成
  7. 開発サーバーを起動:`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.html

myapp/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