Django Enterprise Structure: How Large Django Codebases Are Organized

Organizing and properly separating business concerns in large, enterprise-scale applications.

As Django projects grow from a small application into a serious business platform, the default flat structure starts to break down.

What works for a small prototype:

project/
    settings.py
    urls.py
    users/
    products/
    orders/

often becomes harder to manage when you have: - multiple teams - dozens of apps - hundreds of models - large test suites - CI/CD pipelines - shared internal tooling - years of continuous development

This is where an enterprise Django structure becomes valuable.

What Is an Enterprise Django Structure?

It usually means organizing your Django codebase into a dedicated application package, commonly called:

apps/

or:

src/

Example:

project/
    manage.py
    config/
        settings/
        urls.py
        wsgi.py
        asgi.py

    apps/
        users/
        products/
        billing/
        orders/
        analytics/
        support/

This creates clear separation between: - project configuration - business applications - infrastructure code

Why Large Teams Prefer This Enterprise Approach:

1. Clear Separation of Concerns

Without structure:

project/
    users/
    orders/
    settings.py
    urls.py
    utils.py
    celery.py

Everything mixes together.

With enterprise structure:

  • config/ -> Django runtime config
  • apps/ -> business domains
  • common/ -> shared libraries

Much easier to navigate.

Typical Enterprise Layout

project/
│
├── manage.py
│
├── config/
│   ├── settings/
│   │   ├── base.py
│   │   ├── dev.py
│   │   ├── prod.py
│   │   └── test.py
│   ├── urls.py
│   ├── asgi.py
│   └── wsgi.py
│
├── apps/
│   ├── users/
│   ├── products/
│   ├── inventory/
│   ├── checkout/
│   ├── billing/
│   ├── shipping/
│   ├── analytics/
│   └── support/
│
├── common/
│   ├── logging/
│   ├── permissions/
│   ├── middleware/
│   └── utils/
│
├── requirements/
├── scripts/
└── docs/

config/

This is the Django runtime package.

Contains: - settings - root URLs - WSGI - ASGI - startup config

Why split settings?

Because production, development, tests, staging all differ.

apps/

This contains your business domains.

Examples:

text

1
2
3
4
apps/users
apps/orders
apps/billing
apps/products

Each app should represent a real business capability.

Good examples: - users - payments - subscriptions - inventory - messaging

Bad examples: - helpers - misc - sharedstuff

Article eplaining apps and when to separate business logic: Django Apps Explained A guide on how to organize your apps inside a dedecated apps-directory: Organize Django Apps

common/

This contains reusable internal libraries.

Examples: - common/auth/ - common/logging/ - common/exceptions/ - common/middleware/

These are not business domains. They support all apps.

Why Not Put Everything in apps/?

Because not everything is an app.

Example: - JWT helper - logging formatter - S3 storage adapter - custom middleware - base model mixins

These belong in infrastructure/shared code.

INSTALLED_APPS in Enterprise Projects

python

1
2
3
4
5
6
7
8
9
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",

    "apps.users",
    "apps.products",
    "apps.orders",
    "apps.billing",
]

Internal Structure of Each App

Example:

apps/orders/
    migrations/
    admin.py
    apps.py
    urls.py
    models/
    views/
    tasks.py
    tests/

This avoids giant models.py and views.py.

Why This Scales Better

Team Ownership

Different teams can own apps:

Billing team → apps/billing Growth team → apps/users Ops team → apps/support

Ownership becomes obvious.

Easier Navigation

Need refund logic?

Go to: apps/billing/

Need order fulfillment?

Go to: apps/orders/

Well-designed apps communicate through: - services - selectors - APIs - events/signals

instead of random imports everywhere.

Settings Structure in Enterprise Teams

Instead of one giant settings file: settings.py # 1200 lines

Split the settings file into separate concerns:

config/settings/
    base.py
    local.py
    staging.py
    prod.py
    test.py

base.py

Shared defaults.

local.py

Debug toolbar, sqlite, local email.

prod.py

Security, PostgreSQL, Redis, S3, sentry.

Example Import Pattern inside dev.py and prod.py:

python

1
from .base import *

Then override environment-specific values.

A full article on how to split your settings can be found here: Split Django's settings.py

Common Mistakes in Large Django Projects

1. Giant core app

core/

Contains 80% of business logic.

Eventually becomes unmaintainable.

2. Everything in utils.py

Avoid dumping grounds.

3. Technical Instead of Domain Apps

Bad:

api/ forms/ models/ views/

These are layers, not domains.

4. Circular Imports Between Apps

Use lazy model refs:

models.ForeignKey("orders.Order")

Use services instead of model cross-calls.

Naming Conventions

Prefer:

text

1
2
3
apps/payments
apps/orders
apps/customers

Avoid:

text

1
2
apps/payment_module_v2
apps/order_management_system

Keep names short and business-oriented.

Best Practices

Use enterprise structure when: - project is serious - multiple engineers involved - expected multi-year lifespan - multiple business domains exist - Keep apps domain-driven - Keep config isolated - Keep shared code separate - Prefer services over cross-app chaos

The enterprise Django structure does not add complexity - it is about creating order before chaos appears.

This pattern:

text

1
2
3
config/
apps/
common/

lets Django monoliths scale to surprisingly large systems without losing maintainability.

If your project may exceed 3–5 apps or 2+ engineers, start with enterprise structure early on. Refactoring later is far more expensive.

Join the Newsletter

Practical insights on Django, backend systems, deployment, architecture, and real-world development — delivered without noise.

Get updates when new guides, learning paths, cheat sheets, and field notes are published.

No spam. Unsubscribe anytime.



There is no third-party involved so don't worry - we won't share your details with anyone.