Webアプリ開発を始めたいと思ったとき、Pythonで最初に候補に挙がるフレームワークの1つがDjangoです。
本記事では、Djangoを初めて触る方が「環境構築」から「簡単なアプリ公開」まで一通り体験できるように、できるだけ順序立てて解説します。
途中のコードをそのまま写していくだけでも1つのミニWebアプリが完成するように構成しています。
Djangoとは
Djangoの特徴とメリット

DjangoはPythonで書かれたフルスタックWebフレームワークです。
URLルーティング、テンプレート、ORM、管理画面など、Webアプリ構築に必要な機能が一通り揃っているのが大きな特徴です。
特に次の点がメリットとして挙げられます。
1つ目は「バッテリー同梱主義(batteries included)」です。
ユーザー認証、フォーム処理、CSRF対策、セッション管理など、Webアプリに欠かせない機能が最初から組み込まれているため、学習コストさえ乗り越えれば、毎回同じような実装を繰り返す必要がありません。
2つ目は強力な管理サイト(Django Admin)です。
モデルを1つ定義して少し設定するだけで、管理者向けのデータ管理画面が自動生成されます。
社内ツールや業務システムの初期開発では、この管理サイトが大きな開発効率アップにつながります。
3つ目は堅牢なセキュリティ機能です。
XSSやCSRF、SQLインジェクションなど、よくある脆弱性への対策がフレームワーク側に組み込まれており、正しい使い方をしていれば自然と安全性の高いアプリケーションになりやすいです。
Flaskとの違いとDjangoを選ぶ理由

Pythonの代表的なWebフレームワークとしてよく比較されるのがFlaskです。
2つの違いを簡単に整理します。
Djangoは「フルスタック」であり、標準で多くの機能を持っています。
一方、Flaskは「マイクロフレームワーク」で、非常にシンプルなコアと多数の拡張で構成されます。
つまり、Djangoは最初から多機能で、Flaskは必要なものだけを自分で組み合わせていくスタイルです。
学習という観点では、「Webアプリに必要なもの一式を体系的に学びたいならDjango」、「最低限の構成で自由度高く作りたいならFlask」と考えるとわかりやすいです。
本記事では、Djangoの世界を一周しながら、実務に近い開発フローを体験していくことを狙いとしています。
Djangoで作れるWebアプリの例

Djangoで作れるアプリケーションは非常に幅広いです。
ブログやニュースサイトのようなコンテンツサイトはもちろん、会員制のサービス、ECサイト、予約システムなど、データベースを扱う多くのWebアプリに向いています。
また、Django REST Frameworkなどの拡張を利用すれば、スマホアプリやSPA(React/Vueなど)のバックエンドAPIとしても利用できます。
管理画面や認証機能が最初から用意されているため、業務システムや社内ツールの開発にもよく使われています。
開発環境の準備
Pythonとpipのインストール確認

Djangoを使う前に、まずPython本体とパッケージ管理ツールであるpipがインストールされているかを確認します。
WindowsでもmacOSでもLinuxでも、基本はターミナル(コマンドプロンプト)で次のように確認します。
python --version
pip --version
これでPythonとpipのバージョンが表示されればOKです。
もし「コマンドが見つかりません」のようなエラーが出る場合は、Pythonがインストールされていないか、パスが通っていません。
その場合は、Python公式サイトからインストーラをダウンロードしてインストールしてください。
仮想環境(venv)の作成と有効化

Djangoプロジェクトごとにライブラリを分離するため、仮想環境(venv)を作るのが一般的です。
作業したいディレクトリで次のコマンドを実行します。
# 例: mysite というプロジェクト用ディレクトリを作成
mkdir mysite
cd mysite
# venv という名前の仮想環境を作成
python -m venv venv
作成した仮想環境を有効化します。
# Windows (PowerShell)
venv\Scripts\Activate.ps1
# または (コマンドプロンプト)
venv\Scripts\activate.bat
# macOS / Linux
source venv/bin/activate
有効化に成功すると、プロンプトの先頭に(venv)のような表示が付きます。
これで、以降インストールするライブラリはこのプロジェクト専用になります。
pipでDjangoをインストールする手順

仮想環境が有効になった状態で、Djangoをインストールします。
pip install django
インストールが完了したら、バージョンを確認しておくとよいです。
python -m django --version
これでDjangoの準備が整いました。
以降の作業は、この仮想環境を有効にした状態で進めてください。
はじめてのDjangoプロジェクト作成
django-admin startprojectの使い方

Djangoではまず「プロジェクト」を作成します。
プロジェクトは、サイト全体の設定をまとめる単位です。
先ほど作成したmysiteディレクトリ内で次のコマンドを実行します。
django-admin startproject mysite .
末尾の.は「カレントディレクトリに作成する」という意味です。
これで、manage.pyや設定ファイルを含む一式が生成されます。
プロジェクト構成と各ファイルの役割

典型的なプロジェクト構成は次のようになります。
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
主なファイルの役割は次の通りです。
manage.py
Djangoプロジェクトを操作するためのコマンドラインツールです。開発サーバーの起動やマイグレーションなど、さまざまな操作を実行します。settings.py
プロジェクト全体の設定ファイルです。データベース、アプリの登録、テンプレート、静的ファイルなどをここで管理します。urls.py
URLパターンとビューの対応関係を定義するファイルです。サイトの「入り口」をまとめる役割があります。wsgi.py/asgi.py
本番環境でWebサーバーとDjangoをつなぐためのインターフェースです。当面の入門段階では、存在だけ把握しておけば問題ありません。
開発用サーバー(runserver)の起動と確認

Djangoは、開発用に簡易Webサーバーを内蔵しています。
プロジェクトディレクトリ(ここではmysite)で次のコマンドを実行します。
python manage.py runserver
ターミナルに「Starting development server at http://127.0.0.1:8000/」のような表示が出たら、ブラウザでそのURLにアクセスしてみてください。
Djangoのウェルカムページが表示されれば、プロジェクトの作成とサーバーの起動に成功しています。
Djangoアプリ作成とURLルーティング入門
startappでアプリを追加する手順

Djangoでは、機能ごとに「アプリ(app)」という単位に分割して実装します。
ブログ機能、会員管理機能などを別々のアプリとして切り分けていくイメージです。
まずはシンプルなアプリを1つ作ってみましょう。
python manage.py startapp myapp
これでmyappディレクトリが作成され、中にviews.pyやmodels.pyなどが生成されます。
このアプリをプロジェクトに登録するため、mysite/settings.pyのINSTALLED_APPSに追加します。
# mysite/settings.py の一部
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
# ここに自作アプリを追加
"myapp",
]
urls.pyでURLルーティングを設定する

URLルーティングは「どのURLにアクセスしたとき、どのビュー関数を呼び出すか」を決める仕組みです。
まず、アプリ側にurls.pyを作成し、ビューへのルートを定義します。
# myapp/urls.py
from django.urls import path
from . import views # 同じディレクトリの views.py をインポート
urlpatterns = [
# /hello にアクセスが来たら views.hello を実行する
path("hello/", views.hello, name="hello"),
]
次に、このアプリのURL設定をプロジェクト全体のurls.pyに組み込みます。
# mysite/urls.py
from django.contrib import admin
from django.urls import path, include # include をインポート
urlpatterns = [
path("admin/", admin.site.urls),
# myapp アプリの URL を / の直下に組み込む
path("", include("myapp.urls")),
]
これで/hello/というURLがアプリのhelloビューにルーティングされるようになりました。
views.pyで最初のビュー関数を作る

ビューは、リクエストを受け取ってレスポンスを返すPythonの関数(またはクラス)です。
まずは最もシンプルなビューを作成してみます。
# myapp/views.py
from django.http import HttpResponse
def hello(request):
"""シンプルな挨拶を表示するビュー関数"""
# HttpResponse に文字列を渡すと、そのままブラウザに表示されます
return HttpResponse("こんにちは、Djangoの世界へようこそ!")
開発サーバーを起動(または再起動)し、ブラウザでhttp://127.0.0.1:8000/hello/にアクセスすると、メッセージが表示されるはずです。
これが一番基本的なDjangoアプリの動作です。
Djangoテンプレート(HTML)の基本
テンプレートディレクトリの設定と読み込み

HTMLを直接HttpResponseに書くのではなく、テンプレートとして別ファイルに分けるのが一般的です。
まずアプリ内にテンプレートディレクトリを作ります。
# myapp ディレクトリ内で
mkdir -p templates/myapp
例えばtemplates/myapp/hello.htmlというファイルを作成し、次のように記述します。
<!-- myapp/templates/myapp/hello.html -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Django入門</title>
</head>
<body>
<h1>こんにちは、Djangoテンプレート!</h1>
<p>これはテンプレートから表示されたページです。</p>
</body>
</html>
ビュー側ではrender関数を使ってテンプレートを読み込みます。
# myapp/views.py
from django.shortcuts import render
def hello(request):
"""テンプレートを使ってHTMLを返すビュー"""
# 第1引数: request
# 第2引数: テンプレートのパス (アプリ内 templates/ 以下の相対パス)
return render(request, "myapp/hello.html")
DjangoはデフォルトでINSTALLED_APPS内のtemplatesディレクトリを探索するので、この設定でテンプレートが自動的に見つかります。
テンプレートタグと変数展開の使い方

テンプレートでは、変数展開や簡単なロジックを記述できます。
ビューから値を渡し、テンプレート内で{{ 変数名 }}として利用します。
# myapp/views.py
from django.shortcuts import render
def hello(request):
context = {
"name": "Python太郎",
"message": "テンプレートへようこそ",
}
return render(request, "myapp/hello.html", context)
テンプレート側では次のように記述できます。
<!-- myapp/templates/myapp/hello.html -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Django入門</title>
</head>
<body>
<h1>こんにちは、{{ name }} さん!</h1>
<p>{{ message }}</p>
<!-- if 文や for 文などのテンプレートタグも使えます -->
{% if name %}
<p>ユーザー名が設定されています。</p>
{% else %}
<p>ユーザー名がありません。</p>
{% endif %}
</body>
</html>
ここでは{{ name }}や{{ message }}と書くだけで、ビューで設定した値が自動的にHTMLに埋め込まれます。
また、{% if %}や{% for %}といったテンプレートタグを使うことで、簡単な条件分岐やループも表現できます。
ベーステンプレートで共通レイアウトを作る

Webサイト全体で共通して使うヘッダーやフッターを、毎回コピペするのは非効率です。
Djangoテンプレートの継承機能を使うと、共通レイアウトをベーステンプレートとしてまとめられます。
<!-- myapp/templates/myapp/base.html (ベーステンプレート) -->
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{% block title %}Django入門サイト{% endblock %}</title>
</head>
<body>
<header>
<h1>Django入門デモサイト</h1>
<nav>
<a href="/hello/">ホーム</a>
</nav>
<hr>
</header>
<main>
{% block content %}
<!-- 各ページ固有の内容がここに入ります -->
{% endblock %}
</main>
<footer>
<hr>
<p>© 2025 Django Sample</p>
</footer>
</body>
</html>
このベーステンプレートを継承するページでは、次のように記述します。
<!-- myapp/templates/myapp/hello.html -->
{% extends "myapp/base.html" %}
{% block title %}ホーム - Django入門{% endblock %}
{% block content %}
<h2>こんにちは、{{ name }} さん!</h2>
<p>{{ message }}</p>
{% endblock %}
共通部分をbase.htmlに集約し、個々のページは{% block %}内だけ記述することで、保守性の高いテンプレート構成にできます。
モデルとデータベース
models.pyでモデルクラスを定義する

Djangoでは、データベースのテーブルをモデルクラスとしてPythonで定義します。
例えば、簡単なメモを保存するPostモデルを作ってみます。
# myapp/models.py
from django.db import models
class Post(models.Model):
"""シンプルな投稿モデル"""
title = models.CharField(
max_length=100,
verbose_name="タイトル",
)
content = models.TextField(
verbose_name="内容",
blank=True, # 空でもOK
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name="作成日時",
)
def __str__(self):
"""管理画面などでの表示名"""
return self.title
ここではCharFieldやTextField、DateTimeFieldといったフィールドを組み合わせて、テーブルのカラムを定義しています。
マイグレーションでテーブルを作成する

モデルを定義しただけでは、実際のデータベースにはテーブルが作成されません。
マイグレーションという仕組みを使って、モデル定義をデータベースに反映します。
# モデルの変更を検出してマイグレーションファイルを作成
python manage.py makemigrations
# マイグレーションファイルを実行してDBに反映
python manage.py migrate
makemigrationsは「どのようなテーブルを作る(変更する)か」を表すファイルを生成し、migrateはその内容を実際のデータベースに適用します。
Django ORMでデータを保存・取得する

DjangoのORM(Object Relational Mapper)を使うと、SQLを書くことなくPythonコードでデータベースを操作できます。
簡単な例をmanage.py shellから実行してみましょう。
python manage.py shell
対話シェルで次のように入力します。
from myapp.models import Post
# レコードを作成
post = Post.objects.create(
title="はじめての投稿",
content="Django ORMでデータを保存しました。",
)
# すべてのレコードを取得
posts = Post.objects.all()
for p in posts:
print(p.id, p.title)
1 はじめての投稿
このように、Pythonのメソッド呼び出しでDB操作ができるため、モデル周りの実装が非常にシンプルになります。
フォームとユーザー入力処理
Djangoフォームの基本とフォームクラス作成

ユーザーからの入力を安全に受け取るために、Djangoではフォームクラスを利用します。
モデルと連動させるModelFormを使うと便利です。
# myapp/forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
"""Postモデルに対応するフォーム"""
class Meta:
model = Post
fields = ["title", "content"] # 入力させたいフィールドだけ指定
このフォームクラスをビューで使うことで、入力フォームとバリデーション処理をまとめて扱えます。
GETとPOSTリクエストの処理方法

新規投稿を行うフォームページのビューを実装してみます。
# myapp/views.py
from django.shortcuts import render, redirect
from .forms import PostForm
from .models import Post
def post_new(request):
"""新しい投稿を作成するビュー"""
if request.method == "POST":
# フォーム送信時(POST)
form = PostForm(request.POST)
if form.is_valid():
# バリデーション成功時に保存
form.save()
# 投稿一覧ページ(仮)へリダイレクト
return redirect("post_list")
else:
# 初回アクセス(GET)時は空のフォームを表示
form = PostForm()
return render(request, "myapp/post_form.html", {"form": form})
def post_list(request):
"""投稿一覧を表示するビュー"""
posts = Post.objects.order_by("-created_at")
return render(request, "myapp/post_list.html", {"posts": posts})
URLルーティングも合わせて設定します。
# myapp/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("hello/", views.hello, name="hello"),
path("posts/", views.post_list, name="post_list"),
path("posts/new/", views.post_new, name="post_new"),
]
フォームのテンプレートは次のように書けます。
<!-- myapp/templates/myapp/post_form.html -->
{% extends "myapp/base.html" %}
{% block title %}新規投稿{% endblock %}
{% block content %}
<h2>新規投稿</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">保存</button>
</form>
{% endblock %}
一覧表示側はシンプルに次のような形です。
<!-- myapp/templates/myapp/post_list.html -->
{% extends "myapp/base.html" %}
{% block title %}投稿一覧{% endblock %}
{% block content %}
<h2>投稿一覧</h2>
<p><a href="{% url 'post_new' %}">新規投稿</a></p>
{% for post in posts %}
<article>
<h3>{{ post.title }}</h3>
<p>{{ post.content|linebreaksbr }}</p>
<small>{{ post.created_at }}</small>
</article>
<hr>
{% empty %}
<p>投稿はまだありません。</p>
{% endfor %}
{% endblock %}
バリデーションとエラーメッセージ表示

Djangoのフォームは、バリデーションとエラーメッセージ表示を自動で行ってくれます。
上記のPostFormでは、モデル側でblank=Falseのフィールド(デフォルト)は必須入力となり、未入力の場合は自動的にエラーが表示されます。
エラー表示をより明示的に制御したい場合は、テンプレート側でform.non_field_errorsやfield.errorsを利用できます。
<!-- フォームテンプレート内の一部 (post_form.html) -->
<form method="post">
{% csrf_token %}
<!-- フォーム全体のエラー -->
{{ form.non_field_errors }}
<!-- 各フィールドを個別に表示 -->
<div>
{{ form.title.label_tag }}
{{ form.title }}
{{ form.title.errors }}
</div>
<div>
{{ form.content.label_tag }}
{{ form.content }}
{{ form.content.errors }}
</div>
<button type="submit">保存</button>
</form>
これにより、入力不備があった際にユーザーにとってわかりやすいエラー表示を実現できます。
管理サイト(Django Admin)の活用
superuser作成と管理画面へのログイン

Djangoの大きな魅力の1つが管理サイト(Django Admin)です。
まずはスーパーユーザー(管理者アカウント)を作成します。
python manage.py createsuperuser
ユーザー名、メールアドレス、パスワードを入力して作成が完了したら、ブラウザでhttp://127.0.0.1:8000/admin/にアクセスして、先ほど作成したユーザーでログインしてみてください。
標準で用意されたユーザーやグループ管理画面が表示されます。
モデルを管理サイトに登録する方法

自作したPostモデルを管理サイトから操作できるようにするには、admin.pyで登録します。
# myapp/admin.py
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
"""Postモデルを管理サイトに登録するためのクラス"""
pass # とりあえず何もしない定義
この状態で管理画面を再読み込みすると、「Posts」(または「投稿」)が表示され、ブラウザ上からデータの追加・編集・削除ができるようになります。
管理画面の表示項目と検索のカスタマイズ

管理画面は少しコードを書くことで、ビジネスに役立つツールに早変わりします。
代表的なカスタマイズを見てみましょう。
# myapp/admin.py
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
"""Postモデルの管理画面カスタマイズ"""
# 一覧画面に表示するカラム
list_display = ("id", "title", "created_at")
# 検索対象とするフィールド
search_fields = ("title", "content")
# 絞り込みフィルターに表示するフィールド
list_filter = ("created_at",)
# 1ページあたりの表示件数
list_per_page = 20
このように、わずかなコード追加で高機能な管理ツールが手に入るのがDjango Adminの大きな魅力です。
静的ファイル(CSS・画像・JavaScript)の設定
STATICFILES_DIRSとstaticタグの使い方

Djangoでは、CSSや画像、JavaScriptなどの静的ファイルをstaticという仕組みで管理します。
まず、アプリ内にstaticディレクトリを作成します。
# myapp ディレクトリ内で
mkdir -p static/myapp
例としてstatic/myapp/style.cssを作成し、簡単なスタイルを記述します。
/* myapp/static/myapp/style.css */
/* ページ全体の基本フォントと余白 */
body {
font-family: system-ui, sans-serif;
margin: 20px;
}
/* ヘッダーの装飾 */
header h1 {
color: #2c3e50;
}
article {
margin-bottom: 16px;
}
テンプレート側でこのCSSファイルを読み込むには、staticテンプレートタグを使います。
<!-- myapp/templates/myapp/base.html の <head> 内を一部修正 -->
{% load static %}
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>{% block title %}Django入門サイト{% endblock %}</title>
<link rel="stylesheet" href="{% static 'myapp/style.css' %}">
</head>
<body>
<!-- ここから下は同じ -->
これで、Djangoが開発サーバー経由でCSSファイルを配信し、ページにスタイルが適用されます。
CSSでテンプレートを装飾する手順

CSSを使って少し見た目を整えるだけでも、アプリの印象は大きく変わります。
先ほどのstyle.cssに、例えばリンクやボタンのスタイルを追加してみます。
/* ボタン風のスタイル */
button,
a.button {
display: inline-block;
padding: 6px 12px;
border-radius: 4px;
background-color: #3498db;
color: #ffffff;
text-decoration: none;
}
button:hover,
a.button:hover {
background-color: #2980b9;
}
/* 投稿タイトル */
article h3 {
margin-bottom: 4px;
}
テンプレートでリンクにbuttonクラスを指定すると、次のように表示を変えられます。
<p><a href="{% url 'post_new' %}" class="button">新規投稿</a></p>
このように、テンプレートとstaticファイルを組み合わせることで、ロジックと見た目をきれいに分離できます。
本番環境での静的ファイル収集

開発時は各アプリのstaticディレクトリから直接配信されますが、本番環境では静的ファイルを1カ所に集約してWebサーバー(Nginxなど)から配信するのが一般的です。
settings.pyでSTATIC_ROOTを設定し、次のコマンドを実行します。
# settings.py の一例
STATIC_URL = "/static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
python manage.py collectstatic
これにより、各アプリのstaticフォルダにあるファイルがSTATIC_ROOTにコピーされ、本番Webサーバーからまとめて配信できるようになります。
Djangoアプリのテストとデバッグ
settings.pyのDEBUG設定と注意点

settings.pyにはDEBUGという重要な設定があります。
DEBUG = True
開発中はTrueのままで構いませんが、本番環境では必ずFalseにする必要があります。
DEBUG=Trueのまま公開すると、エラー時に内部情報が漏れてしまう可能性があるためです。
logging設定とエラー画面の確認

Djangoでは、Python標準のloggingを利用してエラーや情報を記録できます。
入門段階では、最低限エラーをコンソールに表示できれば十分ですが、将来的にはファイル出力や外部サービス連携も検討するとよいでしょう。
settings.pyのLOGGING設定を使うと、ログレベルや出力先を細かく制御できます。
また、開発中に意図的にエラーを発生させ、エラー画面やログの内容を確認しておくことも、トラブルシューティングのトレーニングになります。
単体テストと簡単なテストコード例

Djangoはテストフレームワークも内蔵しています。
ビューが正しく動作しているかを確認する簡単なテストを書いてみましょう。
# myapp/tests.py
from django.test import TestCase
from django.urls import reverse
from .models import Post
class PostViewsTests(TestCase):
"""Post関連ビューのテスト"""
def test_post_list_empty(self):
"""投稿が0件のときでも一覧ページが開くこと"""
url = reverse("post_list")
response = self.client.get(url)
# HTTPステータスコード200(OK)であることを確認
self.assertEqual(response.status_code, 200)
# テンプレート内の文言が含まれていることを確認
self.assertContains(response, "投稿はまだありません。")
def test_post_list_with_post(self):
"""投稿が1件あるとき、タイトルが表示されること"""
Post.objects.create(title="テスト投稿", content="本文")
url = reverse("post_list")
response = self.client.get(url)
self.assertContains(response, "テスト投稿")
テストの実行は次のコマンドで行います。
python manage.py test
このような自動テストを少しずつ増やしていくと、機能追加やリファクタリングを安心して行えるようになります。
Djangoアプリの本番公開
本番公開の前に確認すべき設定

本番公開前には、最低限次のポイントを確認しておく必要があります。
まず、DEBUGをFalseに設定します。
次に、ALLOWED_HOSTSに実際のドメイン名またはIPアドレスを設定します。
# settings.py の一部 (本番想定)
DEBUG = False
ALLOWED_HOSTS = ["example.com", "www.example.com"]
また、静的ファイルのcollectstaticを実行し、本番Webサーバーから配信できるように準備しておくことも重要です。
データベースとSECRET_KEYの扱い方

開発時はSQLiteを使うことが多いですが、本番環境ではPostgreSQLなどのRDBMSを利用するケースが一般的です。
その場合、settings.pyのDATABASES設定を変更します。
また、SECRET_KEYやデータベースのパスワードはコードに直書きせず、環境変数や設定ファイル(.env)を用いて外部管理することが推奨されます。
これにより、ソースコードをリポジトリに公開した際の情報漏えいリスクを減らせます。
Python・Djangoアプリのデプロイ方法の選択肢

Djangoアプリの本番公開には、さまざまな方法があります。
学習目的や小規模サービスなら、PaaS(Platform as a Service)を利用するのがおすすめです。
代表例としてはHerokuやPythonAnywhereがあります。
一方、より自由度の高い構成を求める場合は、VPSやAWS EC2などにNginx + Gunicorn(Uvicorn) + Djangoといった構成でデプロイする方法があります。
さらにDockerコンテナを使えば、環境構築をコード化し、再現性の高いデプロイが可能になります。
代表的なDjangoデプロイサービス
HerokuでのDjangoデプロイ手順

Herokuは学習用途や小規模アプリの公開に適したPaaSです。
大まかな流れは次の通りです。
- プロジェクトをGitリポジトリにする
requirements.txtで依存パッケージを定義するProcfileで起動コマンドを定義する- Heroku CLIでアプリを作成し、Gitからデプロイする
Procfileの例を簡単に示します。
# Procfile (例)
web: gunicorn mysite.wsgi --log-file -
詳細な手順や設定はHerokuとDjangoの公式ドキュメントを参照しながら進めると安心です。
VPSやクラウド(AWSなど)での公開ポイント

VPSやAWS EC2上にDjangoをデプロイする場合、典型的な構成は次のようになります。
- Nginx: リバースプロキシ・静的ファイル配信
- Gunicorn(Uvicorn): WSGI(ASGI)アプリケーションサーバー
- Django: アプリ本体
- PostgreSQLなど: データベース
この構成では、ブラウザからのリクエストはまずNginxに届き、DjangoアプリへのリクエストはGunicornを経由して処理されます。
静的ファイルはNginxから直接配信されるため、アプリ本体への負荷を減らせます。
PythonAnywhereなどPaaSでのDjango運用

PythonAnywhereは、ブラウザだけでPython・Djangoアプリを運用できるPaaSです。
GitHubからコードを取得したり、ブラウザ上でファイル編集やコンソール作業を行ったりできるため、ローカル環境の準備が難しい場合にも有用です。
無料枠もあるため、最初の「インターネット上に公開する体験」をするには非常に良い選択肢です。
制約もあるため、本格的な商用サービスでは有料プランや他サービスとの組み合わせを検討します。
次のステップ
認証・ログイン機能の追加

Djangoには認証・ユーザー管理機能が標準搭載されています。
ログイン・ログアウト・パスワード変更などがまとまっているため、ブログの「投稿はログインユーザーだけが行える」といった権限制御も比較的簡単に実装できます。
今後のステップとして、django.contrib.authを活用し、ログインフォーム、ユーザー登録機能、ログイン必須のビュー(@login_required)などを追加していくと、より実用的なアプリに近づきます。
Django REST FrameworkでAPI化

Webブラウザだけでなく、スマホアプリやフロントエンドフレームワーク(React, Vueなど)からも利用できるAPIを提供したい場合、Django REST Framework(DRF)が有力な選択肢になります。
DRFを使うと、シリアライザやViewSetなどの機能により、「モデルの一覧・詳細・作成・更新・削除」といったREST APIを少ないコードで実装できます。
Djangoに慣れてきたら、次のステージとしてAPI開発にも挑戦してみるとよいでしょう。
学習を継続するためのおすすめリソース

Djangoを継続的に学んでいくためのリソースとして、次のようなものがあります。
- Django公式ドキュメントと公式チュートリアル
- 日本語で丁寧に解説された書籍やオンライン講座
- GitHub上のDjangoオープンソースプロジェクトのコードリーディング
特に公式チュートリアルは、投票アプリを例にモデル・ビュー・テンプレート・フォーム・テスト・管理サイトなどを一通り体験できるよう設計されているため、本記事と並行して進めると理解がより深まります。
まとめ
Djangoは、Webアプリに必要な機能が一通り揃ったフルスタックフレームワークです。
本記事では、環境構築からプロジェクト・アプリ作成、テンプレートやモデル、フォーム、管理サイト、静的ファイル設定、テスト、そして本番公開の概要まで、一連の流れを俯瞰しました。
まずはシンプルな投稿アプリを完成させ、次に認証やAPI、より高度なデプロイへと範囲を広げていくことで、実務にも耐えうるDjangoスキルを無理なく身につけていけます。
