Claude CodeでDjangoアプリをMVT構成で開発する手順
Claude CodeにDjango公式チュートリアルの手順を指示しながら、Model・View・TemplateでPollsアプリを組み上げる流れとCLAUDE.md設定のコツを解説します。
Claude CodeでDjangoアプリを作る前に
Claude CodeでDjangoを扱うのに、Django向けの特別な設定は要りません。django-admin や manage.py はただのコマンドラインツールなので、Claude Codeにファイル作成とコマンド実行を任せながら開発を進められます。
この記事ではDjango公式チュートリアルが扱う投票アプリ(polls)を題材に、Model-View-Template(MVT)の3層を順番に実装します。DjangoそのものではなくClaude Codeとの組み合わせ方に焦点を置くため、Django自体の詳しい仕様は公式チュートリアルを参照してください。
MVTはDjango独自の呼び方で、他のフレームワークでよく使われるMVC(Model-View-Controller)とほぼ同じ役割分担です。名前の対応がずれやすいので、ファイルと一緒に並べておきます。
MVTの3層とMVCの対応
Model(models.py)
データを扱う層です。MVCのModelと同じ役割で、このチュートリアルでは
QuestionとChoiceを定義します。View(views.py)
リクエストを受けてレスポンスを返す層です。MVCのControllerに近い位置にあります。
Template(templates/)
画面を組み立てる層です。MVCのViewに近い位置にあります。
前提条件は次の3つです。
- Claude Codeがインストール済みで
claude --versionが通る - Python 3.12以降がインストール済みで、
python -m django --versionでDjangoのバージョンを確認できる - ターミナルの基本操作(
cd、ファイル編集の承認プロンプトへの応答)に慣れている
進め方はDjango公式チュートリアルの構成に沿って3段階です。プロジェクト作成、Modelの定義、View・Templateの実装の順に、Claude Codeへの指示例を挟みながら進めます。
Djangoには「プロジェクト」と「アプリ」という2つの単位があります。プロジェクトはデータベース設定やURL構成をまとめる器で、アプリはその中で動く個々の機能(投票機能、ブログ機能など)です。1つのプロジェクトに複数のアプリを持たせられ、逆に同じアプリを別のプロジェクトへ持ち込むこともできます。この記事では mysite プロジェクトの中に polls アプリを1つ作る、公式チュートリアルと同じ構成で進めます。
プロジェクトを作成し開発サーバーを起動する
まず空のディレクトリでClaude Codeを起動し、プロジェクトの雛形を作らせます。
mkdir djangotutorial && cd djangotutorial
claudeセッション内では自然言語で指示します。
django-adminでmysiteという名前のDjangoプロジェクトをこのディレクトリに作成してくださいClaude Codeは django-admin startproject mysite . 相当のコマンドを実行し、manage.py と mysite/settings.py などを生成します。ターミナルやVS Code拡張で始めたセッションは、Claude Code v2.1.283以降ならAuto modeで始まります。分類器が安全と判断したコマンドは、プロンプトなしで実行されます。それより前のバージョンでは、Auto modeが既定になるのは、Pro・Max・Teamプランでフィーチャーフラグを取得するセッションだけです。
続けて開発サーバーの起動を頼みます。
python manage.py runserverで開発サーバーを起動して、動作確認してくださいhttp://127.0.0.1:8000/ にアクセスして「Congratulations!」ページが表示されれば成功です。開発サーバーはリクエストごとにPythonコードの変更を読み直すので、Claude Codeがviews.pyを書き換えても再起動は要りません。ただしファイルの追加では再起動が走らない場合があると、公式チュートリアルは書いています。テンプレートや新しいモジュールを作らせたあとで画面が変わらないときは、サーバーを止めて起動し直します。動作確認が終わったら、サーバーを動かしているターミナルでCtrl+Cを押して停止します。
最後にpollsアプリを作成します。
manage.py startappでpollsという名前のアプリを追加し、polls/views.pyに"Hello, world. You're at the polls index."を返すindexビューを書いてください。polls/urls.pyでindexにルーティングし、mysite/urls.pyにincludeで組み込んでくださいhttp://localhost:8000/polls/ にアクセスして文言が表示されれば、Viewの最小構成が完成した状態です。
Modelを定義してマイグレーションを反映する
次にDjangoのORMでデータモデルを定義します。今回のpollsアプリでは、質問を表す Question と選択肢を表す Choice の2つのモデルを使います。
polls/models.pyに、Question(question_text: CharField, pub_date: DateTimeField)と、Choice(question: ForeignKey to Question, choice_text: CharField, votes: IntegerField default 0)を定義してください。両方のモデルに__str__メソッドも追加してくださいモデルを追加しただけではデータベースに反映されません。INSTALLED_APPS にアプリを登録したうえで、次の3段階を踏みます。
モデル変更をデータベースに反映する3段階
- 1
models.pyを変更する
Claude Codeに指示してモデルを書かせます。
- 2
makemigrationsでマイグレーションを作る
変更内容が
polls/migrations/0001_initial.pyのようなファイルとして保存されます。人が読んで手で直せるファイルです。バージョン管理に入れれば、本番にも同じものを持ち込めます。 - 3
migrateでデータベースに適用する
まだ適用されていないマイグレーションを、データベースに反映します。
python manage.py makemigrations polls
python manage.py migrateこれらのコマンドをClaude Codeに実行させるときは、Bash権限ルールで扱いを決めておけます。ルールの * は、手前に置いたコマンド部分を固定したまま後ろの引数を受けます。makemigrations は許可し、データベースを書き換える migrate は毎回確認する、という分け方が一例です。
{
"permissions": {
"allow": ["Bash(python manage.py makemigrations *)", "Bash(python manage.py test *)"],
"ask": ["Bash(python manage.py migrate *)"]
}
}一致する ask ルールは、より具体的な allow ルールがあっても確認を出します。Bash(python manage.py migrate *) は、引数なしの python manage.py migrate にも一致します。
管理サイトから直接データを編集できるようにするには、スーパーユーザー作成と admin.py へのモデル登録が必要です。
python manage.py createsuperuserでadminユーザーを作成し、polls/admin.pyでQuestionモデルを管理画面に登録してくださいhttp://127.0.0.1:8000/admin/ にログインすると、Questionの追加・編集・削除ができる管理画面が自動生成されます。Djangoの管理画面はモデル定義から自動生成される機能で、フォームや一覧表示のコードを自分で書く必要はありません。
ViewとTemplateでMVTを完成させる
MVTの最後のピースはTemplateです。detail・results・voteの3つのビューを追加し、indexビューをテンプレート経由の描画に切り替えます。
polls/views.pyにdetail(question_idを受け取りQuestionを表示)、results、voteの3つのビューを追加してください。detailはget_object_or_404で存在しない場合404を返すようにし、polls/urls.pyにapp_name="polls"の名前空間付きでルーティングしてくださいテンプレートはアプリごとのディレクトリに配置します。Djangoは polls/templates/polls/ のように、アプリ名のディレクトリを二重に切る命名規則を使います。これは複数アプリで同名テンプレートが衝突するのを避けるためです。
polls/templates/polls/index.htmlを作成し、latest_question_listをループしてquestion_textをリンク付きで表示してください。リンク先は{% url 'polls:detail' question.id %}を使い、ハードコードしないでくださいindex側のビューは render() ショートカットを使うと簡潔に書けます。
from django.shortcuts import render
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by("-pub_date")[:5]
context = {"latest_question_list": latest_question_list}
return render(request, "polls/index.html", context){% url 'polls:detail' question.id %} のようにURL名を使ってリンクを組み立てると、後から polls/urls.py のパスを変更してもテンプレート側の修正が不要になります。この仕組みはDjango公式チュートリアルの言葉を借りれば、URLをテンプレートにハードコードする密結合を避けるための設計です。
ここまででMVT構成の最小実装が完成します。
Claude CodeでDjango開発を効率化する設定
Djangoプロジェクト固有のルールは、毎回チャットで説明する代わりに CLAUDE.md に書いておくと、セッションをまたいでも再指示が要らなくなります。CLAUDE.mdとSkillsの役割分担にあるとおり、CLAUDE.mdは「常に守ってほしい前提」を書く場所で、多段の手順はSkillsに切り出すのが向いています。
# CLAUDE.md
- manage.py は `.venv/bin/python manage.py ...` の形で実行する(仮想環境の有効化はコマンドをまたいで残らない)
- モデルを変更したら必ず makemigrations → migrate の順で実行する
- テストは `python manage.py test` で実行する
- マイグレーションファイルは生成されたらそのままコミットする(手動編集しない)マイグレーションファイル自体は手で直せますが、上の「手動編集しない」はあくまでチームの運用ルールの例です。
モデルのフィールド変更やマイグレーションの取り消しなど、データベースに影響する変更を加える前にレビューしたい場合はPlan modeが使えます。claude --permission-mode plan で起動するか、セッション中に Shift+Tab でPlan modeへ切り替えます。Plan modeでは、計画を承認するまで編集がブロックされます。ただしbypass permissionsを使える対話型のターミナルセッションではこのブロックが強制されず、計画だけにとどめるよう指示される形になります。
作業を任せる範囲の目安を早見表にまとめます。
| 作業 | Claude Codeに任せる | 理由 |
|---|---|---|
| views.py / urls.py / models.pyの実装 | Claude Codeに任せる◎ | 理由公式チュートリアルの定型パターンが多く、指示と結果の照合がしやすい |
| makemigrations / migrateの実行 | Claude Codeに任せる○ | 理由マイグレーションは人が読めるファイルで残るので、適用前に中身を見られる |
| 本番データベースへのmigrate | Claude Codeに任せる△ | 理由取り消しにくい操作なので、実行前に生成されたマイグレーション内容を自分で確認する |
| SECRET_KEYや本番用DATABASESの設定値 | Claude Codeに任せる△ | 理由環境変数や秘密情報の扱いは自分で最終確認する |
開発サーバーの先へ進むときは、Heroku MCPサーバーでClaude Codeからアプリをデプロイ・スケーリングするが参考になります。コンテナ化して動かす場合はDocker/Podman/Kubernetes MCPの選び方も参照してください。
よくあるつまずき
仮想環境がコマンドに引き継がれない
Bashツールでは、ある実行で行った export が次の実行に残りません。source .venv/bin/activate を実行させても次のコマンドには効かず、システムのPythonで動いて No module named 'django' になります。公式docsは、Claude Codeを起動する前に仮想環境を有効化することを勧め、各コマンドの前に流すスクリプトを指す環境変数 CLAUDE_ENV_FILE も挙げています。手軽なのは、起動前に有効化するか .venv/bin/python manage.py の形で呼ぶ方法です。
INSTALLED_APPSへの追加を忘れたままmakemigrationsを実行する
polls.apps.PollsConfig を mysite/settings.py の INSTALLED_APPS に追加する前に makemigrations polls を実行すると、アプリが認識されずマイグレーションが作られません。モデルを書いた直後は、設定への追加まで含めて指示すると手戻りが減ります。
テンプレートのディレクトリ構造を間違える
polls/templates/index.html のようにアプリ名のサブディレクトリを省略すると、他のアプリに同名テンプレートがある場合にどちらが読み込まれるか制御できなくなります。polls/templates/polls/index.html の二重ディレクトリ構造を崩さないよう、テンプレート作成時は毎回パスを指定して依頼するのが確実です。
開発サーバーがバックグラウンドで残り続ける
runserver を止めずに次のセッションを始めると、同じポートで2つ目のサーバーは起動できません。作業を終えるときは開発サーバーのターミナルでCtrl+Cを押す習慣をつけておきます。
__str__ を書かずに管理画面やシェルで確認する
モデルに __str__ を追加しないと、シェルや管理画面での一覧表示が Question object (1) のような判別しにくい表記になります。Claude Codeにモデルを書かせるときは、フィールド定義と合わせて __str__ の実装まで依頼に含めておくと、その後の動作確認がしやすくなります。
まとめ
任せる範囲の線引きは、取り消しにくさで決めると迷いません。views.pyやmodels.pyの実装、makemigrations のように結果を読んで直せる作業は指示して任せ、migrate のようにデータベースを書き換える操作と本番の設定値は、人が目を通してから通します。
その線引きと仮想環境の呼び方は、CLAUDE.mdと許可ルールに書いておけば毎回の指示が要りません。