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 コンテナを立てて実行します。

関連記事

まとめ

  • Django は ORM・管理画面・認証・フォーム・テストが同梱で、業務 Web システムの土台を素早く用意できる。
  • データ構造は model、変更は migration で管理し、コードと一緒にコミットする。
  • 秘密情報と環境差は環境変数へ。本番は DEBUG=False と WSGI サーバー+リバースプロキシ。
  • アプリと DB をコンテナにまとめ、テストを CI で回すと、開発から運用までの再現性が保てる。

小さく作って管理画面でデータを触りながら育てていけるのが Django の強みです。

LaTeX組版・教材校正のご依頼・ご相談はコレクトコネクトへお問い合わせください。

← コラム一覧へ