6.

Django のよくあるエラー一覧と対処法 — OperationalError から CSRF まで

編集
この記事の要点
  • OperationalError: DB 接続不可、 テーブル不在。 settings.py / migrate / DB 起動を確認
  • DoesNotExist / MultipleObjectsReturned: get() の戻り保証なし。 filter().first()get_or_create() 推奨
  • TemplateDoesNotExist: テンプレートパス・APP_DIRS・TEMPLATE_DIR 確認
  • NoReverseMatch: URL name の typo、 引数数不一致。 {% url "name" arg %} 構文確認
  • CSRF token missing / Forbidden 403: フォームに {% csrf_token %} 必須。 ALLOWED_HOSTS / CSRF_TRUSTED_ORIGINS も

1. OperationalError

DB 関連の最頻出エラー。 接続情報・ネットワーク・テーブル不在など多岐:

django.db.utils.OperationalError: could not connect to server: Connection refused
django.db.utils.OperationalError: (1045, "Access denied for user 'root'@'localhost'")
django.db.utils.OperationalError: no such table: blog_article
django.db.utils.OperationalError: (1146, "Table 'mydb.blog_article' doesn't exist")
原因対処
DB サーバ停止systemctl status postgresql / MySQL サービス起動
接続情報誤りsettings.py の HOST/PORT/USER/PASSWORD 再確認
テーブル不在python manage.py migrate 実行
権限不足DB ユーザに GRANT ALL ON dbname.* TO user@host
ネットワークファイアウォール、 セキュリティグループ確認

2. IntegrityError

制約違反(UNIQUE / NOT NULL / FK):

# UNIQUE 制約違反
django.db.utils.IntegrityError: UNIQUE constraint failed: blog_article.slug

# 対処: 重複チェック後に作成
if not Article.objects.filter(slug=slug).exists():
    Article.objects.create(slug=slug, ...)

# または get_or_create
article, created = Article.objects.get_or_create(
    slug=slug,
    defaults={'title': title, 'body': body},
)

# NOT NULL 制約違反
django.db.utils.IntegrityError: NOT NULL constraint failed: blog_article.author_id

# 対処: 必須フィールドを必ず指定 or モデルに null=True / default 付与

3. DoesNotExist / MultipleObjectsReturned

# DoesNotExist: get() で見つからない
art = Article.objects.get(pk=999)
# blog.models.Article.DoesNotExist: Article matching query does not exist.

# 対処パターン
# 1. filter().first()
art = Article.objects.filter(pk=999).first()  # 無ければ None

# 2. get_object_or_404 (ビューで便利)
from django.shortcuts import get_object_or_404
art = get_object_or_404(Article, pk=999)

# 3. try/except
try:
    art = Article.objects.get(pk=999)
except Article.DoesNotExist:
    art = None

# MultipleObjectsReturned: get() で複数該当
Article.objects.get(category__slug='tech')
# MultipleObjectsReturned: get() returned more than one Article

# 対処: filter() を使う、 または unique 制約見直し
arts = Article.objects.filter(category__slug='tech')

4. TemplateDoesNotExist

django.template.exceptions.TemplateDoesNotExist: blog/article_list.html

# テンプレート検索順序:
# 1. TEMPLATES[0]['DIRS'] のフォルダ
# 2. 各 INSTALLED_APPS の templates/ サブフォルダ (APP_DIRS=True 時)

対処:

  • ファイルパスを確認 — blog/templates/blog/article_list.html 構成が定石(アプリ名サブフォルダ)
  • settings.pyTEMPLATES[0]['APP_DIRS']True か確認
  • プロジェクト共通テンプレートは BASE_DIR / 'templates'DIRS に追加
  • アプリが INSTALLED_APPS に登録されているか確認

5. NoReverseMatch

django.urls.exceptions.NoReverseMatch:
Reverse for 'article_detail' with arguments '(1,)' not found.
1 pattern(s) tried: ['blog/article/(?P[-a-zA-Z0-9_]+)/$']

原因と対処:

  • URL name の typo: urls.pyname='article_detail'{% url 'article_detail' %} を一致させる
  • 引数数の不一致: URL パターンが slug を要求しているのに ID を渡している
  • namespace 必要: {% url 'blog:article_detail' slug=art.slug %}
  • include の app_name: urls.py 冒頭に app_name = 'blog'
# blog/urls.py
from django.urls import path
from . import views

app_name = 'blog'                # namespace

urlpatterns = [
    path('article//', views.detail, name='article_detail'),
]

# テンプレート
{% url 'blog:article_detail' slug=article.slug %}

# Python コード
from django.urls import reverse
reverse('blog:article_detail', kwargs={'slug': art.slug})

6. CSRF Verification Failed (403)

Forbidden (CSRF token missing or incorrect.):
Reason given for failure: CSRF token missing.

POST フォームには必ず {% csrf_token %} 必要:

{% csrf_token %}

HTTPS 環境での追加対処(settings.py):

# Origin 不一致でも 403 になる
CSRF_TRUSTED_ORIGINS = [
    'https://example.com',
    'https://*.example.com',
]
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True

7. DisallowedHost (ALLOWED_HOSTS)

django.core.exceptions.DisallowedHost:
Invalid HTTP_HOST header: 'example.com'.
You may need to add 'example.com' to ALLOWED_HOSTS.
# settings.py
ALLOWED_HOSTS = [
    'example.com',
    'www.example.com',
    '.example.com',           # サブドメイン全部
    '127.0.0.1',
    'localhost',
]

# 開発時のみ全許可(本番禁止)
if DEBUG:
    ALLOWED_HOSTS = ['*']

8. ImproperlyConfigured

django.core.exceptions.ImproperlyConfigured:
The SECRET_KEY setting must not be empty.

django.core.exceptions.ImproperlyConfigured:
Requested setting DATABASES, but settings are not configured.
You must either define the environment variable DJANGO_SETTINGS_MODULE...

対処:

  • SECRET_KEY 未設定: .env から読込み、 または settings.py に直書き(本番は環境変数推奨)
  • DJANGO_SETTINGS_MODULE 未設定: os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')manage.py / wsgi.py 冒頭で
  • NAME 未設定: DATABASES['default']['NAME'] 必須

9. ProgrammingError / FieldError

# ProgrammingError: 存在しないカラム参照(マイグレーション漏れ)
django.db.utils.ProgrammingError: column blog_article.summary does not exist

# 対処: makemigrations + migrate

# FieldError: 不正なフィールド指定
django.core.exceptions.FieldError: Cannot resolve keyword 'titel' into field.
Choices are: author, body, category, created_at, id, slug, ...

# 対処: typo 修正 (titel → title)

10. MIGRATION 関連

症状対処
You have unapplied migrationspython manage.py migrate
Conflicting migrations detectedpython manage.py makemigrations --merge
Migrations for 'app' not detectedapp/migrations/__init__.py がない、 または INSTALLED_APPS 未登録
Inconsistent migration historyDB の django_migrations テーブルと不整合。 環境差分の調査が必要
RemovedInDjangoXX warning非推奨機能。 Django アップグレード前に対処

11. デプロイ後のエラー

  • 500 Internal Server Error: DEBUG=False で詳細が出ない → ログ確認(/var/log/gunicorn/error.log 等)
  • Static files 404: collectstatic 実行漏れ、 nginx の alias 設定誤り
  • ImportError: Couldn't import Django: 仮想環境未有効化、 systemd ユニットの EnvironmentFile 誤り
  • SuspiciousOperation: ALLOWED_HOSTS / SECURE_PROXY_SSL_HEADER 設定漏れ

デバッグのコツ

# 1. DEBUG=True で詳細表示(開発のみ)
DEBUG = True

# 2. django-debug-toolbar
pip install django-debug-toolbar
INSTALLED_APPS += ['debug_toolbar']
MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']
INTERNAL_IPS = ['127.0.0.1']

# 3. ログ設定
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {'class': 'logging.StreamHandler'},
    },
    'loggers': {
        'django.db.backends': {
            'level': 'DEBUG',         # 全 SQL ログ
            'handlers': ['console'],
        },
    },
}

# 4. shell でモデル検証
python manage.py shell
>>> from blog.models import Article
>>> Article.objects.all()

# 5. check コマンド
python manage.py check
python manage.py check --deploy       # 本番向け追加チェック

FAQ

Q: 本番でエラー詳細を見たい
A: DEBUG=False を維持し、 LOGGING でファイル/Sentry に送る。 DEBUG=True 公開は絶対禁止(SECRET_KEY 漏洩リスク)。

Q: マイグレーション地獄から抜けたい
A: 開発初期なら全削除して作り直し。 運用後は --squash で履歴圧縮。

Q: 全エラーを Sentry に飛ばしたい
A: sentry-sdk をインストールし、 settings.pysentry_sdk.init()。 リクエスト情報・スタックトレースが自動収集されます。

編集
Post Share
子ページ
  1. Invalid HTTP_HOST header: '...'. You may need to add '...' to ALLOWED_HOSTS
  2. CommandError: You must set settings.ALLOWED_HOSTS if DEBUG is False.
  3. django.utils.datastructures.MultiValueDictKeyError
  4. Forbidden (403) CSRF verification failed. Request aborted.
  5. ModuleNotFoundError: No module named 'MySQLdb'
  6. WARNINGS: ?: (mysql.W002) MySQL Strict Mode is not set for database connection
  7. Unknown column 'table_name.id' in 'field list'
  8. RuntimeError: Model class ~ doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
  9. get() returned more than one MynumberRegist -- it returned 2!
  10. django.db.utils.OperationalError: (2006, "Can't connect to MySQL server")
  11. 'include' is not defined
同階層のページ
  1. 環境構築とプロジェクト/アプリの作成
  2. MVC(MVT)のそれぞれの使い方と説明
  3. データベースへの接続と操作
  4. Django Administration
  5. git管理
  6. エラー一覧
  7. バージョンの確認方法
  8. ログ出力方法
  9. SQLのログ出力方法
  10. ログのローテート設定
  11. settings.pyの定数にアクセスする方法
  12. 本番環境へのインストールとアプリのデプロイ(apache編)
  13. 本番環境へのインストールとアプリのデプロイ(nginx編)
  14. djangoアプリの本番の開始URLを変更する
  15. 静的(static)ファイルの置き場所と読み込み(画像、css、js )
  16. CSRFトークンをAjaxで使用する方法
  17. ajaxの使用例(POST編)
  18. ファイルのアップロードとファイルの名前
  19. クイックスタート/チュートリアル
  20. ログイン機能
  21. テンプレート側のログイン判定
  22. ビュー側のログイン判定
  23. 管理者ユーザーの作成/判定と管理画面
  24. モデルのjson化とレスポンス
  25. runserverでポートを指定する方法
  26. cronによるバッチ実行
  27. テンプレートで利用する共通のcontextを定義する方法
  28. プログラムが本番サーバーで反映されない場合の対処法
  29. APIの作成
  30. cron用コマンド・ファイルの作成