Skip to content
Latchkey

Django "RuntimeError: Model class doesn't declare an explicit app_label" in CI

Django could not attach a model to an app. Either the app holding the model is missing from INSTALLED_APPS, or the model module was imported before django.setup() ran, so the app registry could not classify it.

What this error means

Import or test collection fails with "RuntimeError: Model class app.models.Thing doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS."

python
RuntimeError: Model class myapp.models.Order doesn't declare an explicit
app_label and isn't in an application in INSTALLED_APPS.

Common causes

The app is not in INSTALLED_APPS

The model lives in an app that the active settings (often a CI settings module) does not list, so Django cannot assign an app_label.

Models imported before Django is set up

A standalone script or conftest imports models before calling django.setup(), so the app registry is not ready to classify the class.

How to fix it

List the app and set up Django first

  1. Add the app to INSTALLED_APPS in the settings used by CI.
  2. In any standalone entry point, set DJANGO_SETTINGS_MODULE and call django.setup() before importing models.
  3. Let pytest-django or manage.py test handle setup instead of importing models manually.
python
import os, django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings.ci")
django.setup()
from myapp.models import Order  # safe after setup()

Use pytest-django so setup runs automatically

pytest-django configures settings and calls setup before collecting tests, so models import cleanly.

pyproject.toml
[tool.pytest.ini_options]
DJANGO_SETTINGS_MODULE = "myproject.settings.ci"

How to prevent it

  • Keep CI settings INSTALLED_APPS in sync with the apps you test.
  • Never import models at module load in scripts that run before setup.
  • Let the test runner own Django initialization.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →