概要(Django の分割構造=「大きな家を部屋ごとに区切る設計」)
Django の「分割構造」は、
一言でいうと「プロジェクト全体を、役割ごと・機能ごとにきれいに分ける仕組み」です。
一番大きな単位が「プロジェクト」、
その中に「アプリ」がいくつも入るイメージです。
プロジェクト=“サイト全体”
アプリ=“サイトの中の機能のまとまり(ブログ機能、会員機能、ショップ機能など)”
さらにアプリの中も、
モデル、ビュー、URL、テンプレート、静的ファイル…と役割ごとに分かれます。
この「分割構造」をちゃんと理解しておくと、
コードが増えても迷子になりにくくなり、
後から機能を追加したり、別プロジェクトに移植したりするのが一気に楽になります。
プロジェクトとアプリの関係をイメージする
プロジェクト=“サイト全体の土台”
django-admin startproject config のようにして作るのが「プロジェクト」です。
例えば、こんな構造になります。
mysite/
manage.py
config/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
ここで大事なのは、
settings.py と urls.py が「プロジェクト全体の中枢」だということです。
settings.py は「このサイトはどんなルールで動くか」を決める場所。
urls.py は「このサイトの入り口(URL)をどう振り分けるか」を決める場所。
プロジェクトは「全体の設定と入り口」を持ち、
実際の機能はアプリに任せる、という役割分担になっています。
アプリ=“機能ごとの部屋”
python manage.py startapp blog のようにして作るのが「アプリ」です。
例えば blog アプリはこんな構造になります。
blog/
__init__.py
admin.py
apps.py
models.py
views.py
urls.py(自分で作る)
templates/(自分で作る)
static/(自分で作る)
migrations/
アプリは「一つの機能のまとまり」です。
ブログ機能なら blog アプリ、
会員管理なら accounts アプリ、
EC 機能なら shop アプリ、
というように分けていきます。
一つのプロジェクトの中に、
複数のアプリが共存するのが Django の基本スタイルです。
アプリの中の分割(models / views / urls / templates / static)
models.py=「データベースの設計図」
models.py には、そのアプリで扱うデータ構造を書きます。
ブログなら Post、Comment、カテゴリなどのモデルがここに並びます。
# blog/models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Pythonこの 1 クラスが DB の 1 テーブルに対応し、
Django ORM を通してデータを読み書きできるようになります。
「データの形とルール」は models.py に集約する、
というのが大事な考え方です。
views.py=「リクエストを受けてレスポンスを返す人」
views.py には、「URL ごとに何をするか」の処理を書きます。
# blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_list(request):
posts = Post.objects.order_by("-created_at")
return render(request, "blog/post_list.html", {"posts": posts})
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, "blog/post_detail.html", {"post": post})
Pythonビューは、
リクエストを受け取る
必要なデータをモデルから取り出す
テンプレートに渡して HTML を作る
という「流れの司令塔」です。
「画面ごとの処理」は views.py に集約する、
というイメージを持っておくと整理しやすくなります。
urls.py(アプリ側)=「そのアプリの入り口の一覧」
blog アプリの中にも urls.py を作り、
そのアプリに関係する URL をまとめます。
# blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.post_list, name="post_list"),
path("<int:pk>/", views.post_detail, name="post_detail"),
]
Pythonこれで、/blog/ → post_list/blog/1/ → post_detail(pk=1)
という対応になります。
プロジェクト側の urls.py では、
この blog.urls を「/blog/ 以下に割り当てる」形で include します。
# config/urls.py
from django.urls import path, include
urlpatterns = [
path("blog/", include("blog.urls")),
]
Pythonこうすることで、
「プロジェクトは大きな入口だけ」「アプリは自分の担当部分だけ」
を書く構造になります。
templates/=「画面の見た目(HTML)の置き場」
テンプレートは、
HTML の中に Django テンプレートタグ({{ }} や {% %})を書いて、
ビューから渡されたデータを埋め込むためのファイルです。
アプリごとにテンプレートを分けるのが定番で、
例えば blog アプリならこうします。
blog/
templates/
blog/
post_list.html
post_detail.html
post_list.html の例はこんな感じです。
<!-- blog/templates/blog/post_list.html -->
<h1>ブログ一覧</h1>
{% for post in posts %}
<h2><a href="{% url 'post_detail' pk=post.pk %}">{{ post.title }}</a></h2>
<p>{{ post.created_at }}</p>
{% endfor %}
「見た目」はテンプレートに閉じ込め、
ビューは「どのテンプレートに何を渡すか」だけを考える、
という分業がポイントです。
static/=「CSS・JS・画像などの静的ファイル」
アプリごとに static フォルダを作り、
その中に CSS や JS、画像などを置きます。
blog/
static/
blog/
style.css
テンプレートからは、{% load static %} を使って参照します。
{% load static %}
<link rel="stylesheet" href="{% static 'blog/style.css' %}">
これで、
「見た目のロジック(HTML)」と「装飾(CSS)」も分離されます。
それぞれがどうつながるかを一気に眺める
リクエストが来てからレスポンスが返るまで
ブログの一覧ページ /blog/ にアクセスされたとき、
裏側ではこんな流れになっています。
ブラウザが /blog/ にリクエストを送る。
プロジェクトの config/urls.py が /blog/ を blog.urls に振り分ける。blog/urls.py の path("", post_list, ...) がマッチし、post_list ビューが呼ばれる。post_list ビューが Post.objects.order_by(...) でモデルからデータを取り出す。
ビューが render(request, "blog/post_list.html", {"posts": posts}) を呼ぶ。
テンプレート blog/post_list.html が posts を使って HTML を生成する。
生成された HTML がレスポンスとしてブラウザに返る。
この一連の流れの中で、
プロジェクト、アプリ、models、views、urls、templates が
それぞれの役割を果たしています。
「どこで何をしているか」が分かると、
バグが出たときに「どこを見ればいいか」も分かるようになります。
アプリを増やしても構造が崩れない理由
例えば、同じプロジェクトに shop アプリを追加したとします。
shop アプリにも models.py, views.py, urls.py, templates/, static/ ができます。
プロジェクト側の urls.py に path("shop/", include("shop.urls")) を足せば、/shop/ 以下は shop アプリの担当になります。
blog と shop は、
お互いの中身を知らなくても動きます。
共通しているのは「Django の約束(分割構造)」だけです。
この「アプリごとに完結していて、プロジェクトがそれらを束ねる」構造が、
Django の分割構造の一番おいしいところです。
設計のときに意識してほしいポイント
「機能ごとにアプリを分ける」感覚を持つ
最初は、
全部を一つのアプリに詰め込みたくなるかもしれません。
でも、
ブログ機能
会員機能
問い合わせフォーム
EC 機能
など、明らかに役割が違うものは、
アプリを分けた方が長期的に楽です。
アプリを分けると、
そのアプリだけを別プロジェクトに持っていくこともできますし、
テストやリファクタリングの単位としても扱いやすくなります。
「1 ファイルに詰め込みすぎない」
views.py に 100 個のビュー関数が並び始めたら、
さすがに読みにくくなります。
そういうときは、
views ディレクトリを作ってファイルを分割したり、
クラスベースビューで整理したりする、
という次のステップに進めばいいです。
大事なのは、
「役割ごとに分ける」という感覚を常に持っておくこと。
モデルは models.py(または models/ 配下)
ビューは views.py(または views/ 配下)
URL は urls.py
テンプレートは templates/
という「分割の軸」を崩さない限り、
細かい分け方は後からいくらでも調整できます。
まとめ(Django の分割構造は「迷子にならないための地図」)
Django の分割構造を初心者目線でまとめると、こうなります。
プロジェクトは「サイト全体の土台とルール(settings, 入口の urls)」を持ち、アプリは「機能ごとのまとまり(blog, accounts, shop など)」としてその中にぶら下がる。
アプリの中は、models(データ)、views(処理)、urls(入り口)、templates(見た目)、static(CSS/JS/画像)と役割ごとに分かれていて、「どの種類のコードをどこに置くか」が明確になっている。
リクエストは「プロジェクトの urls → アプリの urls → ビュー → モデル → テンプレート」という流れで処理され、この流れを一度頭に描けるようになると、Django のコード全体が一気に読みやすくなる。
