(d0-django-module-map)= (Django のモジュール地図)= # 第1部 序章 Django のモジュール地図 — リクエストが通るコードと、受け渡されるデータ 第1章からは、Django・Starlette・FastAPI の**実物のソースコード**を一行ずつ開いていきます。 ただ、いきなり個々のファイルに潜ると、「いま自分は Django というソフトウェアのどこを読んでいるのか」を見失いがちです。 そこでこの序章では、本論に入る前に **Django を俯瞰する地図**を用意します。 地図の描き方には、構造化分析設計技法 **SADT(IDEF0)** の流儀を借ります。 全体を**たった1つの箱**から始めて段階的に分解し、各機能が本書のどの章に対応するかを一覧(図式目次)にする——この地図を手元に置けば、細部のソースに潜っても全体を見失いません。 ```{note} この序章で地図にするのは **Django** です(第1部=第1〜9章、第3部=第16・17章)。 Starlette / FastAPI(第2部=第10〜15章)は別系統のソフトウェアなので、その地図は第2部の序章で改めて描きます。 ``` ## 0.1 この地図の読み方 この地図は、IDEF0 の**段階分解の考え方**を借りつつ、各図は読みやすい**データフロー図**として描いています。約束ごとを4つだけ押さえます。 - **機能は箱、流れは矢印(2種類)**。箱は「何をするか」(起動する・解決する・描画する)を表します。矢印は2種類で、**データの流れは実線**(`environ`・`HttpRequest`・`HttpResponse` など、箱から箱へ受け渡される値)、**制御・資源の流れは破線**(`settings`・`URLconf` や apps レジストリ・DB 接続のように、処理を方向づけたり支えたりするもの)です。 - **段階分解**。系全体を1箱で表す**文脈図**(A-0)から始め、それを主要機能へ分解し(A0)、必要な箱をさらに分解します(A4・A42…)。 - **ノード番号とリーフ**。分解の各ボックスには番号が付きます。**さらに分解される箱はノード番号**(`A4` など)を持ち、対応する子図にリンクします。**それ以上分解しない箱(リーフ)には、代わりに、それを精読する章番号**(`第1章` など)を入れます。 - **図式目次**。分解の階層を一覧にしたものが**図式目次**で、これが本書 Django 編の地図そのものになります。 ## 0.2 A-0:Django 全体を1つの箱で(文脈図) 出発点は、Django のリクエスト処理を**たった1つの箱**で表す文脈図です。 ```{figure} /figures/fig-d0-context.svg :name: fig-d0-context :align: center :width: 100% 図0-1 A-0 文脈図:Django が HTTP リクエストを処理する ``` 実線と破線を読み分けます。 実線のデータは、入力 `environ`/`scope`(WSGI/ASGI)が処理されて、出力のレスポンスのバイト列へと変わります。 破線は、処理の振る舞いを決める `settings`/`URLconf` と、処理を支える資源である `apps` レジストリ・DB 接続です。 「**入力を、設定に従い、資源を使って、出力へ変える**」——この見方を、以降の分解でも一貫して使います。 ## 0.3 A0:箱0をリクエスト処理の機能に分解する A-0 の箱「0」を開くと、Django のリクエスト処理は**5つの機能**に分かれます。 ```{figure} /figures/fig-d0-a0.svg :name: fig-d0-a0 :align: center :width: 100% 図0-2 A0:箱0の分解と、継ぎ目で変わるデータ ``` リクエストは A1 → A5 へと流れます(実線がデータ、破線が制御・資源)。 A1 が**起動時**に一度だけ処理基盤(WSGI callable)を用意し、A2 が `environ` を `HttpRequest` に変換します。 A3 のミドルウェアを `HttpRequest` が通り、A4 がルーティングしてビューを実行し、A5 が `HttpResponse` をバイト列にして返します。 **継ぎ目ごとにデータの型が変わる**(`environ` → `HttpRequest` → `HttpResponse` → `bytes`)点が背骨です。 ボックス右下の番号に注目してください。 箱1・箱2・箱3・箱5 はリーフなので**章番号**(第1章・第2章・第4章・第2章)を、箱4だけは**ノード番号 `A4`**(=さらに分解される)を持ちます。 ## 0.4 A4・A42:ビュー実行の内側へ ノード番号 `A4` を持つ箱4「ルーティングしてビューを実行する」を、子図でさらに開きます。 ```{figure} /figures/fig-d0-a4.svg :name: fig-d0-a4 :align: center :width: 100% 図0-3 A4:箱4の分解(URL 解決 → ビュー → レスポンス組み立て) ``` A41 が URL を解決して `ResolverMatch`(呼ぶべきビュー)を特定し、A42 がそのビューを呼び、A43 が `HttpResponse` を組み立てます。 ここでも箱2(A42)だけがノード番号を持ち、さらに分解されます。 その箱2「ビューを呼ぶ」を開くと、ビューが呼び分ける**3つのサブシステム**が現れます。 ```{figure} /figures/fig-d0-a42.svg :name: fig-d0-a42 :align: center :width: 100% 図0-4 A42:ビューが呼ぶフォーム・テンプレート・ORM ``` 矢印のデータが要点です。 フォームは生の `QueryDict` を検証済みの `cleaned_data` に、テンプレートは `Context` を HTML 文字列に、ORM は `QuerySet` を SQL とパラメータに変えます。 「**宣言を集め、検証し、別の形に変換する**」という同じ骨格が、フォーム(第7章)・テンプレート(第6章)・ORM(第8・9章)のどれにも現れます。 ## 0.5 図式目次(ノードツリー)と、章の対応 ここまでの分解を1枚に束ねたものが**図式目次**です。 **親ボックスから子図への破線リンク**でツリーをたどれます。これが Django 編の地図そのものです。 ```{figure} /figures/fig-d0-nodetree.svg :name: fig-d0-nodetree :align: center :width: 100% 図0-5 図式目次:A-0 → A0 → A4 → A42 の分解と、対応する章 ``` 注意したいのは、**機能の番号(A1〜A5)と章の順番は一致しない**ことです。 リクエストは A1 → A2 → … と流れますが、本書は学びやすさを優先して、入口(第1章)→ Request/Response の解剖(第2章)→ URL 解決(第3章)→ ミドルウェア(第4章)→ ビュー(第5章)→ ビューが呼ぶサブシステム(第6〜9章)の順に読みます。 ```{table} 表0-1 機能ノードと章・主な実物ソースの対応 :name: tbl-d0-node-chapter :widths: auto | ノード | 機能 | 章 | 主に読む実物ソース | |--------|------|----|--------------------| | A1 | 起動・初期化 | 第1章 | `core/wsgi.py`・`core/handlers/wsgi.py`・`apps/registry.py` | | A2 | リクエストを組み立てる | 第2章 | `http/request.py` | | A3 | ミドルウェアを適用する | 第4章 | `core/handlers/base.py`・`middleware/csrf.py` | | A41 | URL を解決する | 第3章 | `urls/resolvers.py` | | A42-1 | フォームで検証する | 第7章 | `forms/forms.py`・`forms/models.py` | | A42-2 | テンプレートを描画する | 第6章 | `template/base.py`・`template/engine.py` | | A42-3 | ORM でデータを取得する | 第8・9章 | `db/models/query.py`・`db/models/sql/compiler.py` | | A43 | レスポンスを組み立てる | 第5章 | `views/generic/base.py` | | A5 | レスポンスを送出する | 第2章 | `http/response.py`・`core/handlers/wsgi.py` | | (境界) | ASGI と sync/async | 第16・17章 | `core/handlers/asgi.py`・`asgiref/sync.py` | ``` ## 0.6 地図を持って、第1章へ ここまでで、Django のリクエスト処理を「機能の箱」と「継ぎ目を流れるデータ」として段階的に分解し、各機能がどの章に対応するかの図式目次を手にしました。 次の第1章からは、この地図の **A1(起動・初期化)** に降りて、`wsgi.py` の数行から Django がどう起動し、`environ` がどこで `HttpRequest` になるのかを、実物のソースで開いていきます。 迷ったら、図0-5 と表0-1 に戻ってください。 いま読んでいるコードが地図のどこにあるかが分かれば、細部に潜っても全体を見失いません。