Django settings are not configured (tested)
ImproperlyConfigured: Requested setting X, but settings are not configured means code touched Django settings outside manage.py without DJANGO_SETTINGS_MODULE. Set it, call django.setup(), then import models.
Setup
A project at /w/proj with mysite/settings.py and an app blog with one model:
SECRET_KEY = 'dev-only'
INSTALLED_APPS = ['django.contrib.contenttypes', 'blog']
DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}}
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
1. Reproduce it: a script that touches settings
import sys; sys.path.insert(0, '/w/proj')
# a standalone script, run with: python b1.py (no manage.py, no env var)
from django.conf import settings
try:
print(settings.DEBUG)
except Exception as e:
print(type(e).__module__ + '.' + type(e).__name__ + ':', e)
Output:
django.core.exceptions.ImproperlyConfigured: Requested setting DEBUG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
manage.py sets DJANGO_SETTINGS_MODULE for you. A plain script, a Jupyter notebook, a test runner started directly, or a Celery worker does not, so the first access to settings (often indirectly, through a Django import) raises this error.
2. Next error: Apps aren't loaded yet
import os, sys; sys.path.insert(0, '/w/proj')
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
# settings are found now, but django.setup() was never called
try:
from blog.models import Post
except Exception as e:
print(type(e).__module__ + '.' + type(e).__name__ + ':', e)
Output:
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
Setting the variable is not enough to import models: the app registry is only filled by django.setup(). Importing blog.models before that raises AppRegistryNotReady.
3. Fix: set the variable, call django.setup(), then import models
import os, sys; sys.path.insert(0, '/w/proj')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
import django
django.setup() # must run before importing models
from blog.models import Post
print(Post._meta.label, Post._meta.db_table)
Output:
blog.Post blog_post
Order matters: os.environ.setdefault(...), django.setup(), and only then imports of models or anything that imports them. For one-off jobs, a custom management command (python manage.py mycommand) avoids all of this, and python manage.py shell is already set up. For pytest, pytest-django reads DJANGO_SETTINGS_MODULE from pytest.ini.
4. The variable is set but the module is not importable
import os, sys, subprocess; sys.path.insert(0, '/w/proj')
code = "import django; django.setup(); print('ok')"
for value in ['mysite.setting', 'settings']: # typo / wrong package level
p = subprocess.run([sys.executable, '-c', code], capture_output=True, text=True,
env={**os.environ, 'DJANGO_SETTINGS_MODULE': value, 'PYTHONPATH': '/w/proj'})
print(value, '->', p.stderr.strip().splitlines()[-1])
Output:
mysite.setting -> ModuleNotFoundError: No module named 'mysite.setting'
settings -> ModuleNotFoundError: No module named 'settings'
The value is a Python import path, resolved against sys.path: mysite.settings needs the directory that contains mysite/ (the one with manage.py) on the path. A typo or a path one level too deep gives ModuleNotFoundError, not ImproperlyConfigured.
Checklist
- Running via
manage.py? If not, setDJANGO_SETTINGS_MODULE(or callsettings.configure()for a settings-free script). - Call
django.setup()before importing models. - Make sure the project root is the working directory or on
PYTHONPATH.
Frequently asked questions
How do I fix 'settings are not configured' in a standalone script?
Set os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings') and call django.setup() before importing models, or turn the script into a management command.
What does 'Apps aren't loaded yet' mean?
Models were imported before django.setup() populated the app registry. Call django.setup() first.
Written with AI assistance. Measured on 2026-10-23 with Django 6.1.2 and Python 3.14.7 (python:3-alpine in Docker). Each block was run verbatim and the output pasted unedited. PlainHeaders is our extension; Python and Django are free.