Django Domain-Driven Design Project Structure
DDD-style Django with bounded contexts, services layer, and explicit domain modeling.
Project Directory
myproject/
manage.py
config/
__init__.py
settings/
__init__.py
base.py
local.py
production.py
urls.py
wsgi.py
asgi.py
src/
All application code
domain/
Bounded contexts
orders/
Order context
__init__.py
domain/
Pure domain logic
__init__.py
entities.py
Order, OrderLine
value_objects.py
Money, Address
events.py
OrderPlaced, OrderShipped
exceptions.py
Domain exceptions
repositories.py
Abstract repository
application/
Use cases
__init__.py
commands.py
CreateOrder, CancelOrder
queries.py
GetOrderDetails
handlers.py
Command/query handlers
services.py
Application services
infrastructure/
Django adapters
__init__.py
models.py
Django ORM models
repositories.py
Concrete repository
admin.py
migrations/
__init__.py
presentation/
API layer
__init__.py
views.py
serializers.py
urls.py
catalog/
Product context
__init__.py
domain/
__init__.py
entities.py
value_objects.py
repositories.py
application/
__init__.py
services.py
infrastructure/
__init__.py
models.py
repositories.py
admin.py
migrations/
__init__.py
presentation/
__init__.py
views.py
urls.py
__init__.py
shared/
Cross-cutting concerns
__init__.py
domain/
__init__.py
base_entity.py
Abstract Entity
base_value_object.py
domain_event.py
Event base class
infrastructure/
__init__.py
event_bus.py
Event dispatcher
unit_of_work.py
Transaction management
__init__.py
tests/
unit/
Domain logic tests
__init__.py
orders/
__init__.py
test_entities.py
test_value_objects.py
integration/
Repository tests
__init__.py
test_repositories.py
e2e/
API tests
__init__.py
test_orders_api.py
conftest.py
Shared fixtures
requirements/
base.txt
local.txt
production.txt
.env.example
.gitignore
pytest.ini
Why This Structure?
This structure isolates domain logic from Django. Each bounded context has layers: domain (entities, value objects), application (use cases), infrastructure (Django ORM), and presentation (API). The domain layer has no Django imports—it's pure Python.
Layer Responsibilities
- domain/-Entities, value objects, domain events—no framework deps
- application/-Use cases, commands, queries—orchestrates domain
- infrastructure/-Django models, repositories—implements interfaces
- presentation/-Views, serializers—maps HTTP to commands/queries
DDD Building Blocks
- Entity-Objects with identity (Order, User)—mutable
- Value Object-Immutable descriptors (Money, Address)—no identity
- Domain Event-Something that happened (OrderPlaced)
- Repository-Collection-like interface for aggregates
Dependency Rule
Dependencies point inward: presentation → application → domain ← infrastructure. The domain layer knows nothing about Django, HTTP, or databases. Infrastructure implements abstract repositories defined in domain.
Bounded Contexts
- orders/-Order placement, fulfillment, cancellation
- catalog/-Products, categories, pricing
- Add more-payments/, shipping/, users/ as needed
Testing Strategy
- tests/unit/-Fast, no DB—test domain logic in isolation
- tests/integration/-Repository implementations with real DB
- tests/e2e/-Full request cycle through API
When To Use This
- Complex business rules that evolve frequently
- Multiple integrations (payments, shipping, etc.)
- Large teams needing clear boundaries
- Long-lived products (5+ years)
- Domain experts actively involved
Trade-offs
- Boilerplate-More files and abstractions than simple CRUD
- Learning curve-Team must understand DDD concepts
- Overkill for simple apps-Don't use for basic CRUD projects