2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Djangoは「どこに何を書くか」が決まっている ― MTVと最小構成

2
Posted at

Djangoは「どこに何を書くか」が決まっている ― MTVと最小構成

articles/views.py を書いてブラウザを開いたのに、Djangoの初期ページのままだった。素朴なPHP構成なら article.php を置いた場所をそのままURLにできますが、Djangoでは何も起きません。ファイルを置いた場所とURLは、まったく関係がないからです。

この挙動は戸惑いやすい一方、裏を返せば「どこに何を書くか」が最初から決まっている、ということでもあります。本記事は「Djangoフレームワーク入門と実践」の第1回として、その決まりごと(MTV)と、プロジェクトが動き出すまでの最小構成を扱います。

シリーズの前半(第1〜3回)では、記事を投稿・表示する小さなCMSを題材にDjangoの基礎を一通り通します。後半(第4回以降)は、姉妹シリーズ「Springフレームワーク入門と実践」と題材を注文受付へ揃えたうえで、同じ処理をSpring Bootで書いた場合と比較していきます。

検証環境はPython 3.11、Django 5.2.17、SQLiteです。2026年8月時点の最新機能リリースはDjango 6.1ですが、このシリーズは長期サポート版(LTS)である5.2系に固定しました。5.2系の公式な延長サポートは2028年4月までで、記事中のリンクも5.2版へ揃えています。

この記事でわかること

  • Djangoが「フルスタック」と呼ばれる理由と、最初から入っているもの
  • MTV(Model・Template・View)が、どのファイルに対応するか
  • startprojectstartapp の関係
  • エラーが出ないまま失敗する2つのつまずき所と、その直し方

選ばなくていい代わりに、Django流に合わせる

DjangoはPythonのフルスタックWebフレームワークです。「フルスタック」が具体的に何を指すかというと、次のものが最初から同梱されているということです。

機能 Djangoでの実体 素朴なPHP構成なら
DB操作 ORM(SQLをほぼ書かない) 自分でSQLを書く/ライブラリを選ぶ
URLルーティング urls.py の対応表 ファイルの配置がそのままURL
管理画面 django.contrib.admin 自作するか、別途用意する
認証・セッション django.contrib.auth 自作するか、ライブラリを選ぶ
開発用サーバ manage.py runserver Apacheやlighttpdを立てる

選ぶ手間がない代わりに、Django流のやり方に合わせる必要があります。この記事で扱うのは、その骨格です。

MTV ― 1つのリクエストが通る道

Djangoの構造はMTV(Model・Template・View)と呼ばれます。名前だけ聞くとMVCの言い換えのようですが、対応するファイルで捉えたほうが早いです。

図はファイル4つを並べただけですが、通る順番と、MTVのどれがどれに当たるかを対応させています。

このCMSの一覧表示で、リクエストが4つのファイルを通る

このCMSの一覧表示を順に追うと、urls.py がURLと処理の対応を決め、views.py が呼ばれ、models.py 経由でデータを取り、テンプレートがHTMLにする、という流れです。すべてのリクエストが必ずこの4段を通るわけではありません。DBを使わず直接レスポンスを返すViewも、Templateを使わずJSONを返すViewも書けます。

  • Model — DBのテーブルをPythonのクラスで書きます。検索や保存もこのクラス経由です
  • View — リクエストを受け取り、Modelからデータを集めてTemplateへ渡す処理です。MVCでいうControllerに近い位置づけです
  • Template — 返すHTMLです。{{ 変数名 }}{% for %} という独自の記法で値を埋め込みます

MVCのViewとMTVのViewは、別のものを指します

MTVで表示を担当するのはTemplateで、Viewは処理側です。MVCの語彙をそのまま当てると、ここを混同しやすくなります。Djangoの公式FAQも、MVCとの対応を説明しています。

設定を持つのがプロジェクト、機能を持つのがアプリ

まず作業用の仮想環境を作ってDjangoを入れます。Django 5.2が公式対応するPython 3.10〜3.14のうち、この記事ではPython 3.11を使います。

python -m venv .venv
source .venv/bin/activate      # Windowsは .venv\Scripts\activate
pip install "Django==5.2.*"

以降のコマンドは、この仮想環境を有効にした状態で実行します。

django-admin startproject mysite
cd mysite
python manage.py startapp articles

1つ目が django-admin、2つ目が python manage.py になっているのは、プロジェクトを作る前と後の違いです。manage.py はプロジェクトと一緒に生成されるので、それ以降はこちらを使います。

startproject で作られる mysite/ がサイト全体の設定を持ちます。settings.py(設定)と urls.py(ルーティングの入口)が中心です。startapp で作られる articles/ が機能のまとまりです。記事機能、ユーザー機能、通知機能……とアプリを分けていく想定になっています。

この時点のファイル構成はこうなります。

mysite/
├── manage.py            ← コマンドの入口
├── mysite/              ← プロジェクト(サイト全体の設定)
│   ├── settings.py
│   ├── urls.py          ← ルーティングの入口
│   └── wsgi.py          ← 本番サーバとつなぐ口
└── articles/            ← アプリ(機能のまとまり)
    ├── models.py
    ├── views.py
    ├── admin.py
    └── migrations/      ← DBへの変更履歴が入る(第2回)

templates/ はこの時点では作られません。自分で作ります(第3回)。

ロケットが出れば、まだ何も定義していなくて正常

python manage.py runserver

http://127.0.0.1:8000/ を開いてロケットの絵が出れば、プロジェクトは動いています。まだURLを1つも定義していないので、この時点ではこの初期ページが出るのが正常です。あとで出てくるつまずき所②で、この画面がもう一度、別の意味で出てきます。

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
Django version 5.2.17, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/

runserver は開発用です。起動時のログにも「本番では使うな」という警告が出ます。本番ではWSGI/ASGIサーバやリバースプロキシを含めた配備構成が別途必要です。このシリーズでは扱いません。

つまずき所 ① ― アプリを登録しないと、何も起きない

ここからが本題です。startapp articles を実行しても、Djangoはまだ articles アプリの存在を知りません。

この状態でモデルを書いて、DBへ反映するためのファイル(マイグレーション。第2回で扱います)を作ろうとすると、こうなります。

$ python manage.py makemigrations
No changes detected
$ echo $?
0

エラーではありません。終了コードも0です。ただ「変更はありません」と言われるだけで、何も起きません。モデル定義だけを見直しても直らず、確認すべき場所はアプリの登録です。

原因は、アプリが登録されていないことです。settings.pyINSTALLED_APPS へ追加します。

# settings.py
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "articles",
]

上の6つは、最初から入っている機能(管理画面・認証・セッションなど)です。Djangoにとっては自前の機能も自分で作るアプリも同じ「アプリ」で、この一覧に並んでいるものだけが有効になります。登録していないものは、黙って無視されます。

認識されているアプリは python manage.py showmigrations で確認できます。articles が並んでいなければ、モデル側をいくら見ても何も出てきません。

つまずき所 ② ― urls.py をつながないと、ロケットのまま

もう1つは、ルーティングです。アプリ側に urls.py を作っても、それだけでは有効になりません。プロジェクト側の urls.py から include() して、初めてURLと結びつきます。

# mysite/urls.py
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("articles.urls")),
]

これを忘れるとどうなるか。/admin/ は問題なく開けるのに、/さっきのロケットの初期ページのままになります。404すら出ません。

urls.py の中身が admin/ だけのとき、Djangoは / に対してこの初期ページを返す仕様だからです(手元で確認すると 200 でした)。DEBUG = False なら404になりますし、urls.py に他のパターンが1つでもあれば404になります。

つまり、同じ画面が2つの状態で現れます。「まだ何も定義していないので正常」と「アプリをつなぎ忘れている」が、見た目だけでは区別できません。views.py を疑う前に、プロジェクト側の urlpatterns を確認するのが近道です。

日本語で使うなら、最初にやっておく設定

# settings.py
LANGUAGE_CODE = "ja"
TIME_ZONE = "Asia/Tokyo"
USE_TZ = True

LANGUAGE_CODEja にすると、管理画面の表示が日本語になります。TIME_ZONE は表示に使うタイムゾーンです。USE_TZ = True(既定値)のときDjangoはDBにはUTCで保存し、表示するときに TIME_ZONE へ変換します。第3回で管理画面を開くと、DBの値と画面の表示が9時間ずれているのを実際に見ることになります。

実務ではこうなる

アプリは、最初から細かく分けないほうがいいです。「機能のまとまり」と言われると10個に割りたくなりますが、アプリをまたぐモデル参照が増えると逆に追えなくなります。今回のCMSも articles 1つで足りました。境界がはっきりしてから分けるほうが動きやすいです。

一方、settings.py の分割と SECRET_KEY の追い出しは、gitへ入れる前に必ず来ます。開発と本番でDB接続先も DEBUG も違うものを1ファイルに書くのは無理がありますし、startproject が生成した鍵はそのまま平文で残っています。どちらも第7回で、Springの外部設定・Profileと並べて扱います。

確認した範囲

Django 5.2.17、Python 3.11。startprojectstartapp 直後のファイル構成、INSTALLED_APPS 未登録の状態で makemigrationsNo changes detected(終了コード0)で終わること、LANGUAGE_CODETIME_ZONE の変更が管理画面の表示に反映されることを、それぞれ実行して確かめました。

つまずき所②は、urls.pyadmin/ だけの状態で / を開き、404ではなくロケットページが 200 で返ることを確認しています。urls.py にもう1つパターンを足すと404に変わることも併せて確認しました。

公式リファレンス

この回で扱った機能

バージョンを選ぶときの根拠

参考文献・参照資料

本記事は公式ドキュメントとサンプルのローカル実行結果を根拠にしています。書籍は参照していません。図は新規に作成したもので、公式資料の図版を引き写したものではありません。

次の第2回では、モデルを書いて実際にテーブルを作ります。makemigrations が生成するファイルの中身と、そこから発行される CREATE TABLE を実際に読み、「SQLを書かない」とはどういう意味かを確認します。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?