ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
基本フロー
# 1. models.py を編集
# 2. マイグレーション生成
python manage.py makemigrations
# Migrations for 'myapp':
# myapp/migrations/0002_article_published_at.py
# - Add field published_at to article
# 3. SQL を確認(実行しない)
python manage.py sqlmigrate myapp 0002
# 4. 適用
python manage.py migrate
# 5. 状態確認
python manage.py showmigrations
生成されたファイルの中身
# myapp/migrations/0002_article_published_at.py
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('myapp', '0001_initial'), # 自アプリの前バージョン
('auth', '0012_alter_user_first_name_max_length'), # 他アプリ依存
]
operations = [
migrations.AddField(
model_name='article',
name='published_at',
field=models.DateTimeField(null=True, blank=True),
),
]
主な Operation
| Operation | 用途 |
|---|---|
CreateModel | テーブル新規作成 |
DeleteModel | テーブル削除 |
RenameModel | テーブル名変更 |
AddField | 列追加 |
RemoveField | 列削除 |
AlterField | 列の定義変更(型・制約) |
RenameField | 列名変更 |
AddIndex / RemoveIndex | インデックス追加・削除 |
AddConstraint / RemoveConstraint | 制約追加・削除 |
AlterModelOptions | Meta オプション変更 |
RunSQL | 生 SQL 実行 |
RunPython | Python 関数実行(データ移行) |
データ移行 (RunPython)
列追加とセットでデータの埋め直しが必要な場合:
# 空のマイグレーションを生成
python manage.py makemigrations myapp --empty -n populate_slug# 0003_populate_slug.py
from django.db import migrations
from django.utils.text import slugify
def forwards(apps, schema_editor):
Article = apps.get_model('myapp', 'Article') # 履歴モデルを使う
for a in Article.objects.all():
if not a.slug:
a.slug = slugify(a.title)
a.save(update_fields=['slug'])
def backwards(apps, schema_editor):
# 元に戻す処理(空にするなど)
Article = apps.get_model('myapp', 'Article')
Article.objects.update(slug='')
class Migration(migrations.Migration):
dependencies = [('myapp', '0002_article_slug')]
operations = [
migrations.RunPython(forwards, backwards),
]
重要: RunPython 内で from myapp.models import Article と直接 import するのは NG。apps.get_model() でその時点のモデル定義を取り出すこと(将来モデルが変わってもマイグレーションが壊れない)。
生 SQL: RunSQL
class Migration(migrations.Migration):
dependencies = [('myapp', '0003_populate_slug')]
operations = [
migrations.RunSQL(
sql="CREATE INDEX CONCURRENTLY idx_article_slug ON myapp_article(slug);",
reverse_sql="DROP INDEX IF EXISTS idx_article_slug;",
),
]
本番デプロイの定石
1. NOT NULL 列を追加するときは 2 段階
# Step 1: nullable で追加 + デフォルト値で埋める
class Article(models.Model):
status = models.CharField(max_length=20, null=True, blank=True)
# → makemigrations / migrate
# Step 2: データを埋める(RunPython)
# → makemigrations --empty で生成
# Step 3: NOT NULL に変更
class Article(models.Model):
status = models.CharField(max_length=20, default='draft')
# → makemigrations / migrate
2. 列削除も段階リリース
- アプリコードからその列の参照を全部消す(古い Pod でも動く状態)
- デプロイして全 Pod が新コードに切替
- 次のリリースで
RemoveField
3. 名前変更 (RenameField)
Django は新旧 2 列が「同名・別フィールド」か「列名変更」か判別できないため、makemigrations 実行時に対話で確認されます。CI で自動化するなら -n オプションで名前付ける。
squashmigrations
マイグレーションが 100 枚溜まって遅い場合、まとめられます:
# 0001 〜 0050 を 1 つにまとめる
python manage.py squashmigrations myapp 0001 0050
# → 0001_squashed_0050_xxx.py が生成される
# 全環境が squashed を適用済になったら、古い 0001〜0050 を削除可能
migrate --fake / fake-initial
# 既存 DB に対し「適用したことにする」(実 SQL は流さない)
python manage.py migrate myapp 0003 --fake
# 既存テーブルが存在する場合、CreateModel 部分だけ fake
python manage.py migrate --fake-initial
# 戻す
python manage.py migrate myapp 0002 # 0002 まで戻る(逆操作実行)
python manage.py migrate myapp zero # 全部戻す
マイグレーションが壊れたとき
# 履歴確認
python manage.py showmigrations
# [X] 0001_initial
# [X] 0002_article_slug
# [ ] 0003_populate_slug ← 未適用
# 履歴を直接見る
SELECT app, name, applied FROM django_migrations WHERE app='myapp' ORDER BY applied;
# 履歴を強制的に書き換え(最終手段)
DELETE FROM django_migrations WHERE app='myapp' AND name='0003_populate_slug';
# その後 migrate --fake で適用扱いにするなど
CI / コードレビューの観点
- マイグレーションファイルは 必ず Git にコミット。アプリコードと同じ PR で
showmigrations --planで適用順をレビュー- 大規模本番では
--plan+sqlmigrateで SQL を全部確認 - ロックを取る DDL(
ALTER TABLE等)は夜間メンテ枠で - PostgreSQL は
CONCURRENTLY系操作をRunSQLで書き、atomic = Falseを指定
FAQ
Q: makemigrations が「No changes detected」と言う
A: アプリが INSTALLED_APPS に登録されていない、または models.py を保存し忘れ。python manage.py makemigrations myapp とアプリ名を明示してみる。
Q: マイグレーションを取り消したい
A: migrate myapp NNNN で過去の番号まで戻れる。migrate myapp zero でそのアプリの全マイグレーションを巻き戻し。
Q: 履歴をリセットしたい(開発環境)
A: migrations/ 配下の 0001 以外を削除 → DB を作り直し → makemigrations + migrate。本番では絶対やらない。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
- Model の定義方法
- マイグレーションファイルの作成
- テーブル定義の確認
- テーブルの作成
- テーブル名 = アプリケーション名 + モデル名の設定変更
- モデルの中身を確認
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Laravel キャッシュクリア完全ガイド(cache:clear / config:clear / 2026-05-18 07:42:07
- プロジェクトの作成と削除 2026-05-18 07:42:07
- インストール直後にNetbeansが反応しない 2026-05-18 07:42:07
- 動画やチャンネルの検索 2026-05-18 07:42:07
- APIキー取得方法 2026-05-18 07:42:07
- チャンネル情報の取得 2026-05-18 07:42:07
- API 入門 — Web API(REST / GraphQL / gRPC / 2026-05-18 07:42:07
- インストール(eclipseプラグイン) 2026-05-18 07:42:07
- Laravel「Dotenv values containing spaces must be surrounded 2026-05-18 07:42:07
- エラー一覧 2026-05-18 07:42:07
- curl: (51) SSL: certificate subject name '~' does not match 2026-05-18 07:42:07
- インストール方法(Windows版) 2026-05-18 07:42:07
- JSONから配列に変換 2026-05-18 07:42:07
- 処理を一定時間待つ 2026-05-18 07:42:07
- A non well formed numeric value encountered 2026-05-18 07:42:07
コメントを削除してもよろしいでしょうか?