Oct 23, 20268 min read

Best Django Setup for AI Coding Agents

How to set up settings, migrations, tests and type checking in a Django project so a coding agent can change models and verify its work, and how the Encore SDK adds Postgres and object storage to the same project.

Django was used by 35 percent of respondents to the 2024 Python Developers Survey, and 12.6 percent of all respondents to the 2025 Stack Overflow Developer Survey worked with it. It gives a coding agent more to work with than most Python frameworks, because the project layout is conventional, models usually live in each app's models.py, and makemigrations writes the migration from a model change.

Agent sessions tend to go wrong in the setup around Django, for example with a DATABASE_URL in a .env that only one developer has, a SQLite database in tests while production runs on Postgres, migrations generated on one branch and forgotten on another, and an ORM that a type checker cannot see into without extra stubs.

Claude Code's guidance for agents is to give them a check they can run, such as tests or a build, and in a Django project that check is a combination of the test suite, manage.py check, makemigrations --check and a type checker, and the setup decides whether the agent can run all of them on its own.

What to weigh when choosing:

  • Where the database connection comes from, and whether an agent can start a fresh session without asking for a .env.
  • Whether tests run against the same database engine as production.
  • Whether a missing migration fails the build.
  • Whether the agent can type check models and views.
  • Where the commands are documented for the agent.

Django setups for AI coding agents at a glance

SetupDatabase and infrastructureBest fit
Encore SDK in DjangoPostgres and buckets declared in Python, started by encore run, isolated by encore test, provisioned in your AWS or GCP accountTeams that want the same database setup locally, in tests and in production
Environment variables with django-environA DATABASE_URL read from the environment, Postgres run by each developerExisting projects that already have local Postgres and a deploy pipeline
pytest-django with PostgresDjango's test database on a local or CI Postgres, driven by pytestProjects that prefer pytest fixtures over TestCase
SQLite for development and testsA file database with no serverPrototypes that will never run Postgres-specific code
Compare the setups in detail
CapabilityEncore SDK in Djangodjango-environpytest-django with PostgresSQLite
Connection settingsBuilt from db.connection_string in settings.pyDATABASE_URL from the environmentWhatever settings provideA file path
Local databaseencore run starts Postgres locallyRun by each developerRun by each developer or CIA file
Test databaseIsolated database supplied by encore testDjango creates test_<name> on the same serverDjango creates test_<name>, with @pytest.mark.django_dbIn-memory database
Same engine as productionYesPostgresYesif production is PostgresYesif production is PostgresNo
MigrationsDjango migrations, run through encore execDjango migrationsDjango migrationsDjango migrations
Object storage and Pub/SubDeclared in Python and provisionedSeparate setupSeparate setupSeparate setup
Production provisioningIn your AWS or GCP accountSeparate toolingSeparate toolingNot applicable

Encore: Postgres and storage for the Django project you have

Encore

Encore combines a conventional Django project, with manage.py, the ORM, admin, auth and sessions, with infrastructure declared in Python through an SDK you add to it, so the Postgres database and object storage buckets the project uses are module-level declarations that Encore provisions locally, in tests, in preview environments and in your own AWS or GCP account. Django keeps owning the schema and its migrations, and the agent no longer needs a .env with a connection string to start working, because encore run starts Postgres locally and hands the connection to the settings module.

Application code passes through Encore and infrastructure guardrails to resources provisioned in your own AWS or GCP account.
Encore provisions the infrastructure your application needs in your own AWS or GCP account.

The resources live in one module, declared without an Encore migrations directory, because Django manages the schema:

# storage/resources.py from encore.storage import objects from encore.storage import postgres uploads = objects.Bucket("uploads") # Django manages the schema through its own migrations. db = postgres.Database("django")

settings.py builds Django's standard PostgreSQL configuration from the connection string Encore supplies, parsed with psycopg so escaping and connection options are kept:

# config/settings.py (excerpt) from psycopg.conninfo import conninfo_to_dict from storage.resources import db connection = conninfo_to_dict(db.connection_string) DATABASES = { "default": { "ENGINE": "django.db.backends.postgresql", "NAME": connection.pop("dbname"), "USER": connection.pop("user", ""), "PASSWORD": connection.pop("password", ""), "HOST": connection.pop("host", ""), "PORT": connection.pop("port", ""), "OPTIONS": connection, } }

Management commands run through Encore so they receive the same runtime configuration, which gives the agent one way to generate and apply migrations in any environment:

~/django-app
$ encore exec -- uv run python manage.py makemigrations$ encore exec -- uv run python manage.py migrate$ encore run
Django generates and applies its migrations against the database Encore provisions, and encore run starts the project.

Under encore test, pytest runs against an isolated database, and a module fixture applies Django's migrations to it before the tests that need the ORM:

# tests/test_orm.py import pytest from django.core.management import call_command from django.db import connections from django.test import Client from config.wsgi import application # Configure Django and load its apps. from storage.models import Note @pytest.fixture(scope="module") def migrated_database(): # Encore supplies the isolated database; Django owns its schema. call_command("migrate", interactive=False, verbosity=0) yield connections.close_all() def test_create_note(migrated_database): response = Client().post("/notes/", {"title": "hello"}) assert response.status_code == 201 assert Note.objects.filter(title="hello").exists()

Views can use the bucket through asgiref.sync.async_to_sync, since Encore's storage API is async and classic Django views are synchronous. The local MCP server gives the agent the database schema, traces and a way to query the local database, and a deploy provisions the same database as RDS on AWS or Cloud SQL on GCP, with preview environments for each pull request.

Key features

Good to know

Encore provisions the database but does not run Django migrations automatically, so committed migrations still need applying, and Django ORM queries are not traced because they go through psycopg rather than the SDK. The example project adds django-stubs and Pyright as dev dependencies, which works the same with or without Encore. Python support is in beta, and you can sign up for access.

Try Encore →

Environment variables with django-environ

Django

The common setup reads the connection from the environment, following the twelve-factor pattern, with django-environ parsing a DATABASE_URL into Django's format:

# config/settings.py (excerpt) from pathlib import Path import environ BASE_DIR = Path(__file__).resolve().parent.parent env = environ.Env() environ.Env.read_env(BASE_DIR / ".env") DATABASES = {"default": env.db("DATABASE_URL")}

Key features

  • One settings module for every environment, with values from the environment.
  • Works with any hosting setup and any Postgres.

Good to know

The agent needs a working .env and a running Postgres before anything works, so a .env.example and the start command belong in AGENTS.md. It also helps to keep real credentials out of the agent's reach, and Claude Code can deny reads of .env files.

Try django-environ →

pytest-django with Postgres

pytest-django runs Django tests with pytest fixtures, while Django itself still creates a separate, blank test database and destroys it after the run:

import pytest from orders.models import Order @pytest.mark.django_db def test_create_order(client): response = client.post("/orders/", {"email": "ada@example.com"}) assert response.status_code == 201 assert Order.objects.count() == 1

Pair it with checks that fail when an agent forgets a migration or leaves a configuration error:

~/django-app
$ python manage.py makemigrations --check$ python manage.py check$ pytest
makemigrations --check exits non-zero when model changes have no migration.

Key features

  • Fixtures such as client and django_db instead of TestCase classes.
  • Each test runs in a transaction that is rolled back by default.
  • makemigrations --check makes a missing migration a failing check.

Good to know

The test database is created on whatever server the settings point at, so a Postgres server still has to be running for the agent and in CI.

Try pytest-django →

SQLite for development and tests

SQLite is Django's default and needs no server, which makes it tempting for agent sessions, but it also accepts things Postgres rejects, and Postgres features such as JSONField lookups, array fields and some constraints behave differently or do not exist, so an agent can get a green test run for code that fails on the production database, so it is best kept for prototypes, with tests switched to Postgres before agents start writing migrations.

How to choose

  • Encore SDK in Django when you want Postgres and storage provisioned the same way locally, in isolated test databases, in preview environments and in your own AWS or GCP account, with Django keeping its ORM and migrations.
  • django-environ for projects with existing local Postgres and a deploy pipeline, with the setup written into AGENTS.md.
  • pytest-django with Postgres for any of the above, together with makemigrations --check and manage.py check in CI.
  • SQLite only for prototypes.

For Django next to FastAPI and Flask, see FastAPI vs Django vs Flask, and for a wider comparison, see the best Python backend frameworks.

Frequently asked questions

What is the best Django setup for AI coding agents?

Keep the database connection out of hand-edited files, commit every generated migration and fail CI with makemigrations --check, run tests against real Postgres in a separate test database, add django-stubs and Pyright so the agent can type check, and document the commands in AGENTS.md or CLAUDE.md. Encore covers the database part by provisioning Postgres for the project locally, in tests and in your own AWS or GCP account, while Django keeps its ORM, admin and migrations.

How do I use Encore with an existing Django project?

Add the encore-dev package, declare the database with postgres.Database("django") in a resources module, and build DATABASES in settings.py from db.connection_string using psycopg's conninfo_to_dict. Django keeps owning the schema, so you run makemigrations and migrate through encore exec, and encore test gives the test suite an isolated database. Python support in Encore is in beta.

Should Django tests use SQLite when an AI agent runs them?

Not if production runs on Postgres. SQLite accepts queries and constraints that Postgres treats differently, so an agent can get a passing suite for code that fails in production. Run the tests against Postgres instead; Django already creates a separate, blank test database and destroys it after the run.

Deploy to your cloud on AWS and Google Cloud
without managing infrastructure

Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.

~/orders — claude
Claude Code
Claude Code v2.1.180Opus 5.5~/orders