Deploy Django With the Official MongoDB Backend

Use the official django-mongodb-backend in production: connect to MongoDB Atlas or a replica set, set ObjectId primary keys, handle migrations and contrib apps, configure indexes, transactions, and connection pooling, and know its current limitations.

Problem statement

For years, using MongoDB with Django meant unofficial projects that fell out of maintenance. MongoDB now publishes an official Django database backend, django-mongodb-backend, that lets the Django ORM, admin, and many contrib apps work against MongoDB, with support for embedded documents and MongoDB-specific queries. Teams with existing MongoDB data or document-shaped models can use it, but production deployment needs attention to version pairing, primary keys, migrations for contrib apps, replica sets for transactions, and the features the backend does not yet support.

Django on MongoDBDjango ORMmodels and adminMongoDB backendtranslates queriesPyMongo poolto the replica setMongoDB Atlasor self-hosted RSThe backend translates ORM operations into MongoDB queries through PyMongo.
  1. Install the backend version that matches your Django feature release (its version numbers track Django's, such as 5.2.x for Django 5.2).
  2. Configure DATABASES with the backend's URI helper and your MongoDB connection string.
  3. Set DEFAULT_AUTO_FIELD to the backend's ObjectIdAutoField, and use its project template or migration settings for contrib apps.
  4. Connect to a replica set (Atlas clusters are replica sets) so transactions and retryable writes work.
  5. Define indexes in Meta.indexes and apply them with migrations.
  6. Check the backend's documented limitations before relying on complex ORM features.

Step-by-step solution

1. Install matching versions

pip install "django-mongodb-backend==5.2.*" "django==5.2.*"

The backend is tied to Django's internals, so each release supports one Django feature release. Upgrading Django means upgrading the backend in step; pin both in your lock file.

2. Configure the database

import django_mongodb_backend

DATABASES = {
    "default": django_mongodb_backend.parse_uri(
        env("MONGODB_URI"),            # mongodb+srv://app:...@cluster0.example.mongodb.net/?retryWrites=true&w=majority
        db_name="myapp",
    ),
}
DEFAULT_AUTO_FIELD = "django_mongodb_backend.fields.ObjectIdAutoField"

MongoDB's native _id is an ObjectId, so models use ObjectId primary keys instead of integers. Check the backend documentation for the exact helper names in your version; the API has evolved as the project matured.

3. Contrib apps and migrations

Django's contrib apps (admin, auth, contenttypes) ship migrations that assume integer primary keys. The backend provides a project template and app config classes that use ObjectId fields and points MIGRATION_MODULES at compatible migrations. Start new projects from that template:

django-admin startproject myproject --template https://github.com/mongodb-labs/django-mongodb-project/archive/refs/heads/5.2.x.zip

For an existing project, follow the backend's migration guide carefully; switching primary key types after data exists is a data migration, not a settings change.

what changes for a Django projectPostgreSQLdjango-mongodb-backendPrimary keysinteger or UUID!ObjectIdAutoFieldContrib app migrationsbuilt in!MIGRATION_MODULESTransactionsalways availableneeds a replica setJoins and complex SQLfull SQL!documented limitsPlan for these differences before migrating an existing appdjango-deployment.com
New projects adapt easily; converting an existing relational app is a larger project.

4. Replica sets, transactions, and pooling

MongoDB supports multi-document transactions only on replica sets or sharded clusters. Atlas always provides a replica set; a self-hosted single mongod must be started as a one-member replica set for transactions. PyMongo manages a connection pool per process (maxPoolSize in the URI, default 100); with Gunicorn's workers and threads, total connections are processes times pool size, so set a sensible limit:

mongodb+srv://app:pass@cluster0.example.mongodb.net/?maxPoolSize=20&retryWrites=true&w=majority

5. Indexes and embedded documents

Define indexes as usual so they are created by migrations:

class Order(models.Model):
    customer_email = models.EmailField()
    created_at = models.DateTimeField()

    class Meta:
        indexes = [models.Index(fields=["customer_email", "-created_at"])]

The backend also offers MongoDB-specific fields such as embedded models and arrays, which avoid joins for document-shaped data. Use them where data is naturally nested; keep references for data shared across documents.

6. Security and operations on Atlas

Restrict network access to your app servers' IPs or use private endpoints, create a database user with access only to the app database, store the URI as a secret, and enable Atlas backups with point-in-time recovery for production clusters.

Django on MongoDB, production basicsBackend version matches Djangopin both togetherObjectId primary keys from day oneproject templateReplica set for transactionsAtlas or one-member RSmaxPoolSize sized for workersprocesses x poolNetwork access and backups on Atlasprivate endpoint, PITRVersion pairing and primary keys are the decisions that are hard to change laterdjango-deployment.com
Read the backend's limitations page for your version before committing.

Verification check: python manage.py migrate completes, the admin lets you create and edit objects, python manage.py check --deploy passes, and a test transaction that writes two documents rolls back cleanly when an exception is raised.

Explanation

A Django database backend translates ORM operations into the database's query language. For MongoDB, the backend compiles querysets into aggregation pipelines and commands sent through PyMongo, maps model fields to BSON types, and implements schema operations (collections and indexes) for migrations. Because MongoDB has no schema in the SQL sense, migrations mainly create collections and indexes. Some relational features translate poorly or not at all, which is why the backend documents limitations and why document-shaped models get the most benefit.

Edge cases / notes

  • Third-party apps that rely on raw SQL or database-specific features may not work.
  • Integer IDs in URLs become ObjectId strings; update URL converters and any code that assumes integers.
  • Search. Atlas Search and vector search are available through MongoDB-specific query features rather than Django's PostgreSQL search module.
  • Maturity. The backend is newer than Django's core backends; follow its release notes closely.

Next steps

FAQ

Does Django officially support MongoDB?

Django core does not, but MongoDB maintains an official third-party backend, django-mongodb-backend.

Can I use the Django admin with MongoDB?

Yes, with the backend's ObjectId-aware contrib app configuration and migrations.

Do I need a replica set?

For transactions and retryable writes, yes. Atlas clusters are replica sets by default.

Can I switch an existing PostgreSQL Django app to MongoDB?

It is possible but substantial: primary keys, migrations, and some queries change. Plan it as a migration project.

Keep going