ご覧いただきありがとうございます!
領護(りょうご)です。
マスタデータやテストデータを開発開始時に追加しておきたいことってありませんか?
この記事では、post_migrateシグナルを使用して、migrateコマンド実行時に初期データをデータベースへ自動追加する方法を解説します。
とても簡単に実装できるので是非試してみてください!
実行環境
今回の解説で使用する環境は以下の通りです。
Docker Desktop:4.43.2
Python:3.13.5
Django:5.2.4
Sqlite3
ディレクトリ構成
sample_web/
├── .env # 環境変数ファイル
├── db.sqlite3 # SQLiteデータベースファイル
├── docker-compose.yml # Docker Compose設定ファイル
├── Dockerfile # Dockerイメージ定義ファイル
├── manage.py # Django管理スクリプト
├── requirements.txt # プロジェクトの依存ライブラリ一覧
│
├─home # Djangoアプリケーションフォルダ
│ ├── admin.py # 管理サイト設定ファイル
│ ├── apps.py # アプリケーション設定ファイル
│ ├── management.py # カスタム管理コマンドやシグナルハンドラなどを配置
│ ├── models.py # データベースモデル定義ファイル
│ ├── tests.py # テストファイル
│ ├── urls.py # アプリケーションのURLルーティング
│ ├── views.py # ビュー関数/クラス定義ファイル
│ └── __init__.py # Pythonパッケージとして認識させるためのファイル
│ └─migrations # データベーススキーマ変更履歴(マイグレーションファイル)
│ ├── 0001_initial.py # 初期マイグレーションファイル
│ └── __init__.py # Pythonパッケージとして認識させるためのファイル
│
└─sample_project # Djangoプロジェクトのメイン設定フォルダ
├── asgi.py # ASGI互換Webサーバーエントリーポイント
├── settings.py # プロジェクトの主要設定ファイル
├── urls.py # プロジェクト全体のURLルーティング
├── wsgi.py # WSGI互換Webサーバーエントリーポイント
└── __init__.py # Pythonパッケージとして認識させるためのファイル
今回の解説では、上記のディレクトリ構成を使用します。
主に扱うファイルは、home/admin.py、home/apps.py、home/management.py、home/models.pyの4つです。
モデルを定義する
例として使用するモデルをhome/models.pyに作成します。
今回は、ゲームカテゴリーを管理するモデルを作成してみます。
from django.db import models
# ゲームカテゴリー管理モデル
class Category(models.Model):
# ID(手動入力)
id = models.PositiveIntegerField(primary_key=True, unique=True, verbose_name="ID")
# ゲームカテゴリー名
name = models.CharField(max_length=50, unique=True, verbose_name="ゲームカテゴリー名")
class Meta:
verbose_name = "ゲームカテゴリー"
verbose_name_plural = "ゲームカテゴリー"
ordering = ["id"]
def __str__(self):
return f"{self.id}: {self.name}"
ID(手動入力)とゲームカテゴリー名の2つのフィールドを作成します。
通常、DjangoのIDフィールドはAutoFieldで自動的に連番が振られます。
今回は、挙動を分かりやすくするため、あえてPositiveIntegerFieldを使用して手動入力にしています。
データを自動追加するコードを作成
次に、データベースに初期データを追加するコードをhome/management.pyに作成します。
management.pyファイルは新規作成してください。
from .models import Category
# マイグレーション完了後に初期カテゴリーデータを追加するハンドラ
def create_initial_data(sender, **kwargs):
# 追加したい初期データ
initial_categories_data = [
{"id": 1, "name": "アクション"},
{"id": 2, "name": "RPG"},
{"id": 3, "name": "アドベンチャー"},
{"id": 4, "name": "シミュレーション"},
{"id": 5, "name": "ストラテジー"},
{"id": 6, "name": "パズル"},
{"id": 7, "name": "スポーツ"},
{"id": 8, "name": "レース"},
{"id": 9, "name": "ホラー"},
{"id": 10, "name": "音楽"},
]
# 作成数カウント
created_count = 0
# データをDBに追加
for category_data in initial_categories_data:
# idとnameが一致すれば既存とみなし、なければ新規作成またはID衝突エラー
category, created = Category.objects.get_or_create(
id=category_data["id"], name=category_data["name"]
)
# 新規作成した場合はカウントを加算
if created:
created_count += 1
print(f"--- 初期カテゴリーデータの追加が完了しました ({created_count}件追加) ---")
データベースに初期データを追加するコードです。
重要部分を詳しく解説しますね。
# 追加したい初期データ
initial_categories_data = [
{"id": 1, "name": "アクション"},
{"id": 2, "name": "RPG"},
{"id": 3, "name": "アドベンチャー"},
{"id": 4, "name": "シミュレーション"},
{"id": 5, "name": "ストラテジー"},
{"id": 6, "name": "パズル"},
{"id": 7, "name": "スポーツ"},
{"id": 8, "name": "レース"},
{"id": 9, "name": "ホラー"},
{"id": 10, "name": "音楽"},
]
データベースに追加したい初期データを配列(リスト)と辞書を使って定義しています。
この形式は視認性が高く、管理しやすいのでおすすめです。

上記のゲームカテゴリーをデータベースに10レコード追加します。
# 作成数カウント
created_count = 0
# データをDBに追加
for category_data in initial_categories_data:
# idとnameが一致すれば既存とみなし、なければ新規作成またはID衝突エラー
category, created = Category.objects.get_or_create(
id=category_data["id"], name=category_data["name"]
)
# 新規作成した場合はカウントを加算
if created:
created_count += 1
Djangoのメソッドであるget_or_create()を使用して初期データを追加します。
指定したidとnameが完全に一致するデータがデータベースに存在する場合、その既存のデータを取得します。
もし一致するデータがなければ、新しいデータを新規作成してデータベースに追加します。
これにより、migrateコマンドを何度実行しても、同じデータが重複して追加されることを防いでいます。
「created_count」は、実際に新規作成されたデータの数をカウントしています。
最後にその結果を出力することで、正しくデータが追加されたか確認できます。
migrate実行時にコードを実行する
migrateコマンド実行時に、先ほど作成したコードが自動で実行されるように設定します。
初期データを追加したいアプリケーションのapps.pyファイル(今回の例ではhome/apps.py)にコードを追加します。
from django.apps import AppConfig
from django.db.models.signals import post_migrate
class HomeConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "home"
# migrateコマンド実行時、ゲームカテゴリーデータをDBに追加
def ready(self):
from .management import create_initial_data
post_migrate.connect(create_initial_data, sender=self)
migrateコマンド実行時に、先ほど作成したコードを発火させるためのコードです。
重要部分を詳しく解説しますね。
# migrateコマンド実行時、ゲームカテゴリーデータをDBに追加
def ready(self):
from .management import create_initial_data
post_migrate.connect(create_initial_data, sender=self)
Djangoアプリケーションがロードされる準備ができた時に呼び出されるメソッドのready()を使用して、post_migrate()を実行しています。
post_migrate()が実行されると、先ほど作成した初期データをデータベースに追加する関数であるcreate_initial_data()を実行するように登録しています。
このように設定しておくことで、アプリのマイグレーション完了時にのみ初期データが自動で追加されます。
Django管理画面に表示する
データが正しく追加されたかを確認するため、Djangoの管理画面にCategoryモデルを表示するように設定します。
home/admin.pyに以下のコードを作成します。
from django.contrib import admin
from .models import Category
# Categoryモデルの管理サイトでの表示設定
class CategoryAdmin(admin.ModelAdmin):
# 一覧画面に表示するフィールド
list_display = ("id", "name")
# 検索ボックスの対象とするフィールド
search_fields = ("name",)
# デフォルトの並び順
ordering = ("id",)
admin.site.register(Category, CategoryAdmin)
Djangoの管理画面にCategoryモデルを表示するコードです。
idとnameが表示されるように設定しました。
これで準備完了です!
migrationsとmigrateを実行する
データベースにモデルの変更を反映し、同時に初期データを追加します。
python manage.py makemigrations
python manage.py migrate
ターミナルで「makemigrations」と「migrate」コマンドを実行してDBに反映させます。
初期データが追加されたか動作確認

Django管理画面の「HOME」アプリの下に「ゲームカテゴリー」という項目が追加され、クリックするとmigrate実行時に追加された10個のゲームカテゴリーデータが表示されています。
これでmigrateコマンド実行時に、データベースへ初期データを自動追加することができました!
最後に
今回は、Djangoのmigrateコマンド実行時に、データベースへ初期データを自動追加する方法を解説しました。
開発環境で必須となるマスタデータや、テスト用のダミーデータを投入する際に非常に役立ちます。
ぜひ使ってみてください!