# Python Django Review Checklist Extends the generic checklist with Django-specific items. ## Interface Layer (Django Views / DRF) - [ ] DRF: Serializers validate all input fields explicitly - [ ] DRF: `serializer.is_valid(raise_exception=True)` used consistently - [ ] DRF: Permission classes set on every ViewSet - [ ] Function-based views have `@require_http_methods` decorator - [ ] Django forms have `clean_*` methods for custom validation ## Business Layer - [ ] Business logic in services/managers, not in views - [ ] `transaction.atomic()` wraps multi-table writes - [ ] `select_for_update()` used for pessimistic locking where needed - [ ] `@transaction.atomic` decorator on methods with multiple DB writes ## Data Layer (Django ORM) - [ ] `select_related()` for foreign key access in loops - [ ] `prefetch_related()` for many-to-many access in loops - [ ] `QuerySet.exists()` instead of `len(queryset)` for existence checks - [ ] `QuerySet.count()` instead of `len(queryset)` for counts - [ ] `QuerySet.only()` or `defer()` for large tables with unused columns - [ ] Migrations are generated and reviewed (`makemigrations` + `check --deploy`) ## Error Handling - [ ] Custom exception middleware or DRF exception handler - [ ] `DEBUG = False` in production (prevents stack trace leaks) - [ ] `LOGGING` configured with appropriate levels per module - [ ] Sentry or similar error tracking integrated ## Security (Django) - [ ] `SECRET_KEY` not hardcoded — loaded from environment - [ ] `ALLOWED_HOSTS` properly restricted - [ ] `SECURE_SSL_REDIRECT`, `SESSION_COOKIE_SECURE`, `CSRF_COOKIE_SECURE` enabled - [ ] `X_FRAME_OPTIONS`, `SECURE_HSTS_SECONDS` set - [ ] CSRF middleware enabled (default) - [ ] File upload: `FILE_UPLOAD_MAX_MEMORY_SIZE` and validation ## Performance - [ ] Celery tasks for async operations with proper retry config - [ ] Django cache framework used with appropriate backend (Redis/Memcached) - [ ] Database indexes on filtered/sorted fields - [ ] `iterator()` for large querysets to avoid memory issues - [ ] `bulk_create()` / `bulk_update()` for batch operations