◀ 8.

RuntimeError: Model class ~ doesn't declare an explicit

▶
この記事の要点
  • Django の RuntimeError: Model class ~ doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
  • 意味: 「このモデルがどのアプリに属するか判断できない」
  • 原因 1(最多): モデルを含むアプリが settings.py の INSTALLED_APPS に登録されていない
  • 原因 2: apps.py の name と実際のパッケージパスの不一致、import パスの書き方の違い
  • 原因 3: Django の外のスクリプトで django.setup() 前にモデルを import している

エラー内容

RuntimeError: Model class ~ doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.

「~」の部分には myapp.models.Article のようなモデルのクラス名が入ります。python manage.py runserver・migrate・shell の起動時や、テスト実行時に発生します。

原因: モデルがどのアプリに属するか分からない

Django のモデルは必ずどこかの「アプリ」に属し、そのアプリのラベル(app_label)でテーブル名やマイグレーションが管理されます。Django はモデルクラスが定義されたモジュールのパスを、INSTALLED_APPS に登録されたアプリと照合して所属を決めます。照合できず、モデルの Meta に app_label も書かれていないとこのエラーになります。

原因よくある状況
INSTALLED_APPS への登録漏れstartapp で作ったアプリを settings.py に追加し忘れた
apps.py の name の不一致アプリをフォルダごと移動・リネームしたのに name = 'myapp' が古いまま
import パスの違い登録は 'myapp' なのに、コード側で from myproject.myapp.models import ... のように別のパスで import している
サードパーティのアプリの登録漏れdjango.contrib.auth や django.contrib.contenttypes を外した、ライブラリの説明にあるアプリを追加していない
Django 外のスクリプトバッチや Jupyter で django.setup() の前にモデルを import した

対処法 1: INSTALLED_APPS にアプリを追加する

最も多い原因です。対象のモデルを含むアプリを settings.py の INSTALLED_APPS に登録します。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',                      # ← 追加
    # 'myapp.apps.MyappConfig',   # AppConfig を指定する書き方でも可
]

エラーメッセージに出ているモデルのパス(例: blog.models.Post)の先頭部分が、登録すべきアプリ名の目安です。

対処法 2: apps.py の name を確認する

アプリをサブフォルダに置いている場合(例: apps/blog/)は、apps.py の name をPython のパッケージパス全体にします。

# apps/blog/apps.py
from django.apps import AppConfig

class BlogConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'apps.blog'      # 'blog' ではなくフルパス
# settings.py
INSTALLED_APPS = [
    # ...
    'apps.blog',
]

そのうえで、コード内の import も from apps.blog.models import Post のように同じパスに揃えます。アプリ内からは from .models import Post の相対 import にすると、パスの揺れが起きにくくなります。

対処法 3: Django 外のスクリプトでは setup してから import

import os
import django

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
django.setup()

from myapp.models import Article   # setup の後で import する

定期実行するバッチは、この方法よりも Django のカスタム管理コマンド(python manage.py コマンド名)として作るほうが確実です。

対処法 4: app_label を明示する(特殊なケース)

アプリのフォルダ外にモデルを置く必要があるなど、どうしても所属を自動判定できない場合は、Meta で明示できます。ただし、通常は対処法 1・2 で直すのが正攻法です。

class Article(models.Model):
    title = models.CharField(max_length=200)

    class Meta:
        app_label = 'myapp'   # INSTALLED_APPS に登録済みのアプリのラベル

確認方法

# 設定全体のチェック
python manage.py check

# 登録済みアプリのラベル一覧を表示
python manage.py shell -c "from django.apps import apps; print([a.label for a in apps.get_app_configs()])"

一覧に目的のアプリのラベルが無ければ、INSTALLED_APPS の登録か apps.py の設定に問題があります。修正後は python manage.py makemigrations を実行し、モデルのマイグレーションが作られることも確認しましょう。

関連

子ページ

子ページはありません

同階層のページ
  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