Django による Web システムの構築
はじめに
問い合わせ管理、教材や答案のデータベース、会員向けのページ ── こうした「画面と業務データがある Web システム」を一から作るとき、Django は手堅い選択肢です。ORM、管理画面、認証、フォーム、テストの枠組みが最初から揃っており、必要なものを自作せずに本題に取りかかれます。
この記事では、Django で Web システムを立ち上げてから運用に乗せるまでの流れを、要点だけ通しで整理します。
全体像
Django のアプリは プロジェクト(サイト全体の設定)と、その中の複数の アプリ(機能のまとまり)で構成します。処理は次のように流れます。
リクエスト → urls.py(振り分け)→ view(処理)→ model(DB 読み書き)
↓
レスポンス ← template(HTML 生成)←──────┘
Model(データ)・Template(表示)・View(制御)で役割を分けるこの構成を、Django では MTV と呼びます。
最初の一歩
仮想環境を作り、Django を入れてプロジェクトを開始します。
python -m venv .venv
source .venv/bin/activate
pip install django
django-admin startproject config .
python manage.py runserver
http://127.0.0.1:8000/ が開けば動いています。機能ごとに アプリ を追加します。
python manage.py startapp contacts
作ったアプリは settings.py の INSTALLED_APPS に登録します。
モデルとマイグレーション
データ構造は models.py にクラスとして書きます。
from django.db import models
class Contact(models.Model):
name = models.CharField("お名前", max_length=100)
email = models.EmailField("メール")
body = models.TextField("本文")
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.name}({self.created_at:%Y-%m-%d})"
モデルを変えたら、その差分を マイグレーション として生成し、DB に適用します。
python manage.py makemigrations
python manage.py migrate
マイグレーションファイルはコードと一緒に Git で版管理します。開発では SQLite が既定で動きますが、本番は PostgreSQL など本格的な DB に切り替えます(設定は後述)。
管理画面
Django の管理画面は、モデルを登録するだけで CRUD 画面が手に入ります。データ投入や校正作業に重宝します。
# contacts/admin.py
from django.contrib import admin
from .models import Contact
@admin.register(Contact)
class ContactAdmin(admin.ModelAdmin):
list_display = ("name", "email", "created_at")
search_fields = ("name", "email")
python manage.py createsuperuser
/admin/ からログインできます。
URL・ビュー・テンプレート
urls.py でパスをビューに割り当て、ビューでデータを用意し、テンプレートで HTML にします。
# config/urls.py
from django.urls import path
from contacts import views
urlpatterns = [
path("contact/", views.contact, name="contact"),
]
テンプレートは継承(base.html を各ページが extends する)で共通部分をまとめます。
フォームと認証
入力画面は forms.ModelForm を使うと、モデルからフォームとバリデーションが生成されます。ログイン・ログアウト・パスワード変更は django.contrib.auth がひととおり用意しているので、URL を組み込むだけで使えます。会員限定ページはビューに @login_required を付けます。
静的ファイルと設定の分離
- 静的ファイル(CSS/JS/画像):開発中は自動配信、本番は
collectstaticで 1 か所に集めて Web サーバーから配信します。 - 秘密情報と環境差:
SECRET_KEY、DB のパスワード、DEBUG、ALLOWED_HOSTSはsettings.pyに直書きせず、環境変数から読みます。
import os
DEBUG = os.environ.get("DJANGO_DEBUG", "0") == "1"
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "").split(",")
本番で DEBUG = True のまま公開しない、が鉄則です。
コンテナで動かす
開発・本番の環境差をなくすため、Docker でアプリと DB をまとめます。
# Dockerfile
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["gunicorn", "config.wsgi", "--bind", "0.0.0.0:8000"]
# compose.yaml
services:
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- dbdata:/var/lib/postgresql/data
web:
build: .
environment:
DJANGO_SECRET_KEY: ${DJANGO_SECRET_KEY}
DATABASE_URL: postgres://postgres:${DB_PASSWORD}@db:5432/postgres
ports:
- "8000:8000"
depends_on:
- db
volumes:
dbdata:
DB データは名前付きボリュームに置き、コンテナを作り直しても消えないようにします。
デプロイの勘所
本番に出す前に必ず通す手順があります。
python manage.py migrate… DB スキーマを最新にpython manage.py collectstatic --noinput… 静的ファイルを集約DEBUG=False、ALLOWED_HOSTSを実ドメインに設定- アプリは開発サーバー(
runserver)ではなく gunicorn などの WSGI サーバーで動かし、前段に nginx などのリバースプロキシを置く - HTTPS 化、
SECURE_*系の設定、SECRET_KEYの管理
テストと CI
Django にはテストランナーが組み込まれています。
python manage.py test
これを GitHub Actions と同じ要領で push・PR ごとに走らせれば、壊れた変更が main に入るのを防げます。PostgreSQL が要るテストは、ワークフローの services: に DB コンテナを立てて実行します。
関連記事
- Docker の基本 — アプリと DB をコンテナにまとめる前提
- Northflank — コンテナ化した構成をそのままデプロイする
- Hugo と GitLab で静的 Web サイトを作る — 動く処理の要らないサイトはこちら
- Git と GitHub の基本 — マイグレーションをコードと一緒に管理する
- LaTeX コンパイルを GitHub Actions で自動化する —
manage.py testを CI で回す考え方
まとめ
- Django は ORM・管理画面・認証・フォーム・テストが同梱で、業務 Web システムの土台を素早く用意できる。
- データ構造は model、変更は migration で管理し、コードと一緒にコミットする。
- 秘密情報と環境差は環境変数へ。本番は
DEBUG=Falseと WSGI サーバー+リバースプロキシ。 - アプリと DB をコンテナにまとめ、テストを CI で回すと、開発から運用までの再現性が保てる。
小さく作って管理画面でデータを触りながら育てていけるのが Django の強みです。