Zunku /
ecommerce-django
Scalable Django e-commerce API with JWT auth, Redis caching, Celery workers, and production-ready architecture.
Loading repository data…
CristianMz21 / repository
Production-ready e-commerce REST API · Django + DRF · cache, filters, optimized queries
Production-grade e-commerce backend built with Django 6.0.4 and Django REST Framework 3.17.1. Implements role-based access control, Redis-backed caching, optimized database indexes, and custom analytics endpoints.
CachingMixin)django-filter integrated for query-param filtering across all endpoints/reports/ endpoint aggregating sales, top products, and inventory metrics| Layer | Tools |
|---|---|
| Runtime | Python 3.14 |
| Framework | Django 6.0.4, Django REST Framework 3.17.1 |
| Cache | Redis via django-redis 6.0.0 |
| Filtering | django-filter 25.2 |
| Database | SQLite (dev) — drop-in PostgreSQL ready |
| Tests | Django APITestCase |
| Type checking | mypy 1.20.2 strict mode |
ecommerce_api/ # Project config (settings, root URLs, WSGI/ASGI)
├── settings.py # Environment-based settings
└── store/ # Domain app
├── models.py # Category, Product, Order, OrderItem
├── serializers.py # DRF serializers (per-action variants)
├── services.py # Business logic layer (ReportsService)
├── views.py # ViewSets + CachingMixin + custom actions
├── urls.py # DRF DefaultRouter
├── admin.py # Django admin registration
└── tests.py # API integration tests (28 tests)
The CachingMixin (in store/views.py) wraps all read operations with Redis-backed caching:
def list(self, request: Request, *args: Any, **kwargs: Any) -> Response:
cache_key = self.get_cache_key_list(request)
if cache_key is None:
return super().list(request, *args, **kwargs)
cached = cache.get(cache_key)
if cached:
return Response(cached)
response = super().list(request, *args, **kwargs)
cache.set(cache_key, response.data, timeout=CACHE_TTL)
return Response(response.data)
Writes (POST/PATCH/DELETE) invalidate related caches via _invalidate_related_caches(), ensuring consistency without stale reads.
class AdminOrReadOnlyViewSet(viewsets.ModelViewSet[Any]):
def get_permissions(self) -> list[BasePermission]:
if self.action in ("create", "update", "destroy", "partial_update"):
return [IsAdminUser()]
return super().get_permissions()
This means anyone can browse the catalog, but only authenticated admins can mutate it or access analytics.
git clone https://github.com/CristianMz21/ecommerce-api.git
cd ecommerce-api
uv venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python manage.py migrate
python manage.py createsuperuser
python manage.py runserver
API is now live at http://localhost:8000/api/.
Note: Redis is required for caching. If you don't have it locally, run
docker run -d -p 6379:6379 redis:alpineor comment outCACHESinsettings.py.
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /api/categories/ | public | List all categories |
GET | /api/categories/{id}/ | public | Retrieve category |
POST | /api/categories/ | admin | Create category |
PATCH | /api/categories/{id}/ | admin | Update category |
DELETE | /api/categories/{id}/ | admin | Delete category (if no products with OrderItems) |
GET | /api/products/ | public | List products (filters: category__slug, is_active, price__gte, price__lte, search, ordering) |
GET | /api/products/{id}/ | public | Retrieve product |
GET | /api/products/featured/ | public | List featured products |
GET | /api/products/discounted/ | public | List discounted products |
GET | /api/products/reports/ | admin | Sales + inventory analytics |
POST | /api/products/ | admin | Create product |
# All active products in electronics category, priced 100-500
curl 'http://localhost:8000/api/products/?category__slug=electronics&is_active=true&price__gte=100&price__lte=500'
All changes pass these checks before commit:
pre-commit run --all-files # ruff format, ruff check, mypy, check yaml
python manage.py test store # 28 tests
python scripts/check_suppressions.py --strict # zero suppressions
python manage.py test store
Coverage spans:
djangorestframework-simplejwt)drf-spectacularMIT — see LICENSE.
Built by Cristian Arellano Muñoz — Backend Engineer · Software Architect. Looking for a backend engineer? Let's talk: hi@cristianarellano.com or book a call.
Selected from shared topics, language and repository description—not editorial ratings.
Zunku /
Scalable Django e-commerce API with JWT auth, Redis caching, Celery workers, and production-ready architecture.