Best File Structure for Django REST Framework (DRF) Projects
Organize Your DRF Project Like a Senior Developer: Scalable, Async/Async, AI-Ready, and Dockerized

When building professional-grade Django REST Framework (DRF) projects, having a clean, maintainable file structure is essential. A proper structure allows you to scale your app, integrate AI/ML, async tasks, hooks, and even containerize it with Docker for deployment.
Here’s the ultimate guide for a senior-developer-ready DRF project structure:
my_project/
│
├── manage.py
├── requirements.txt
├── pyproject.toml / poetry.lock
├── .env # Environment variables
├── Dockerfile # For containerization
├── docker-compose.yml # Optional for multi-service setup
│
├── config/ # Project-level settings
│ ├── __init__.py
│ ├── settings.py # Base settings
│ ├── settings_dev.py # Development
│ ├── settings_prod.py # Production
│ ├── urls.py # Root routing
│ ├── asgi.py # Async support
│ └── wsgi.py # Sync support
│
├── apps/ # All Django apps live here
│ ├── __init__.py
│ ├── users/ # Authentication, user management
│ │ ├── __init__.py
│ │ ├── models.py
│ │ ├── serializers.py
│ │ ├── views.py
│ │ ├── urls.py
│ │ ├── permissions.py
│ │ └── signals.py # Hooks
│ │
│ ├── ai/ # AI/ML integration
│ │ ├── __init__.py
│ │ ├── models.py
│ │ ├── serializers.py
│ │ ├── views.py
│ │ ├── services.py # AI inference logic
│ │ └── tasks.py # Async tasks (Celery/RQ)
│ │
│ ├── core/ # Shared utilities
│ │ ├── __init__.py
│ │ ├── utils.py
│ │ ├── mixins.py
│ │ ├── decorators.py
│ │ └── exceptions.py
│ │
│ └── other_apps/...
│
├── scripts/ # CLI scripts, data migration, seeding
│ ├── seed_db.py
│ └── cleanup.py
│
├── tasks/ # Background tasks (Celery/RQ)
│ ├── __init__.py
│ └── ai_tasks.py
│
├── static/ # Collected static files
├── media/ # Uploaded files
├── templates/ # Optional: browsable API or email templates
└── logs/ # Application logs
Folder-by-Folder Explanation:
1. config/
Contains settings, URLs, ASGI/WGI.
Environment separation: dev, prod, staging.
ASGI for async views and WebSockets.
2. apps/
Each app is modular: users, AI, payments, etc.
Keeps business logic separate from routes.
AI app example:
services.py→ business logictasks.py→ background async tasksviews.py→ API endpointsAsync view example:
from rest_framework.views import APIView from rest_framework.response import Response from .tasks import async_inference class PredictView(APIView): async def post(self, request): data = request.data task = async_inference.delay(data) return Response({"task_id": task.id})
3. signals.py
Contains hooks for post_save, pre_save, notifications, logging.
from django.db.models.signals import post_save from django.dispatch import receiver from .models import User @receiver(post_save, sender=User) def send_welcome_email(sender, instance, created, **kwargs): if created: print(f"Send email to {instance.email}")
4. scripts/
For CLI tasks like DB seeding, cleanup, batch updates.
# scripts/seed_db.py import os import django from faker import Faker os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings_dev") django.setup() from apps.users.models import User fake = Faker() def seed_users(n=100): for _ in range(n): User.objects.create(username=fake.user_name(), email=fake.email(), is_active=True) print(f"{n} users created!") if __name__ == "__main__": seed_users()
5. Static, Media, Templates
static/→ CSS, JS, images for front-end or adminmedia/→ uploaded filestemplates/→ optional HTML for emails or browsable APISenior developers collect static files with:
python manage.py collectstatic
6. Docker Integration
Dockerfile:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000"]
docker-compose.yml:
version: "3.9"
services:
web:
build: .
ports:
- "8000:8000"
env_file:
- .env
volumes:
- .:/app
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
- Benefits: easy deployment, dev/prod parity, isolated services
7. Why This Structure Works
Modular apps → easier collaboration
Async ready → WebSockets, background tasks, AI inference
Scripts → DB seeding, cleanup, batch jobs
Static/Media management → clean separation of assets
Dockerized → production-ready
Core utilities → DRY principle, reusable code
Hooks/Signals → maintainable event-driven logic
Bonus Tips
Version APIs →
urls/v1/,urls/v2/Use
pytestfor tests inside each appKeep
.envsecret keys separateSeparate Celery workers for AI or CPU-heavy tasks
Conclusion
A well-structured DRF project is critical for maintainability, scalability, and performance. This structure allows you to:
Integrate AI/ML
Handle async workflows efficiently
Maintain hooks/signals cleanly
Manage static and media files
Deploy seamlessly with Docker
Following this structure will make your project production-ready, collaboration-friendly, and easy to maintain, just like senior developers do.
