2025 update for ecommerce api using Django Ninja/Django Ninja Extra and Postgres
- Python 3.11
- Django 5.1
- Django Ninja
- Django Ninja Extra a collection of extra features for Django Ninja
- Django Ninja JWT
- Django Simple JWT abstraction for Django Ninja
- Postgres database
- Pydantic
- Django Unfold Admin
- Docker & Docker Compose
- pytest for testing
- Gunicorn for production serving
- Makefile to run commands
- PyTest for unit tests
- Custom Start App command to create a new app
- with extended functionality for Django Ninja, Django Ninja Extra, and Django Unfold
make startapp <app_name>
- Faker for generating fake data.
- See
@/core/management/commands/generate_core_data.py
for more information
- See
- Swagger for API documentation
- Debug Toolbar for debugging
- Django Environ for managing environment variables
- Linting
# Clone the repository
git clone https://github.com/mattjaikaran/django-ninja-boilerplate
cd django-ninja-boilerplate
# Create environment file
cp .env.example .env
# Edit .env with your settings
# Start the services
docker-compose up --build
Visit http://localhost:8000/api/docs for the API documentation.
git clone https://github.com/mattjaikaran/django-ninja-boilerplate
cd django-ninja-boilerplate
# Create and activate virtual environment
python3 -m venv env # create a virtual environment using the venv virtual environment
source env/bin/activate # activate the virtual environment
touch .env # create a new env file
# update the .env file with necessary values -> db info, superuser info
pip3 install -r requirements.txt # install dependencies from requirements.txt
python3 manage.py migrate # apply migration files to your local db
python3 manage.py create_superuser # runs custom script to create a superuser
./scripts/generate_secret_key.sh # generate new secret key
python3 manage.py runserver # run the local server on http://localhost:8000/admin
# start a new django app with extended functionality
# for Django Ninja, Django Ninja Extra, and Django Unfold.
$ make startapp <app_name>
$ make runserver
This runs pip install , then pip freeze > requirements.txt to update the requirements.txt file
$ make install <library-name>
# example
# make install django-ninja-jwt
$ make db-setup
The project includes several powerful scripts to enhance the development workflow, located in the scripts/
directory.
test_feature.sh
: Test specific features or endpointsreset_test_data.sh
: Reset and seed test datacheck_health.sh
: Check API health and dependenciesdb_setup.sh
: Set up database and run migrationssetup.sh
: Initial project setuplint.sh
: Run linting checksgenerate_secret_key.sh
: Generate Django secret key
Test specific parts of the API with detailed output:
# Test all product-related endpoints
./scripts/test_feature.sh products
# Test cart features with verbose output
./scripts/test_feature.sh -v cart
# Test authentication endpoints
./scripts/test_feature.sh auth
# Test all features
./scripts/test_feature.sh all
Reset and seed test data for development:
# Reset all test data
./scripts/reset_test_data.sh
# Reset only product data
./scripts/reset_test_data.sh -a products
# Force reset without confirmation
./scripts/reset_test_data.sh -f
# Reset data without running migrations
./scripts/reset_test_data.sh --no-migrations
Monitor the health of your API and dependencies:
# Run all health checks
./scripts/check_health.sh
# Run with verbose output
./scripts/check_health.sh -v
# Check specific API URL
./scripts/check_health.sh -u http://localhost:8001
# Skip specific checks
./scripts/check_health.sh --skip-deps --skip-db
All developer scripts include:
- Colored output for better visibility
- Verbose mode for detailed information
- Help documentation (
-h
or--help
) - Error handling with descriptive messages
- Consistent formatting and logging
For more detailed documentation about the scripts, see scripts/README.md
.
- Django Ninja uses Pydantic models (Schemas) for serialization, not Django serializers like in DRF.
- The response parameter in the route decorator specifies the expected response format.
- Use from_orm() to convert Django ORM objects to Pydantic models.
- Django Ninja automatically handles the conversion to JSON in the HTTP response.
- Update
.env
with production settings - Build and run with Docker:
docker-compose -f docker-compose.prod.yml up --build -d
# Run all tests
pytest
# Run specific test file
pytest path/to/test_file.py
# Run with coverage
pytest --cov=.
- Swagger UI:
/api/docs
- ReDoc:
/api/redoc
- JWT Authentication
- Passwordless Authentication
- PostgreSQL Database
- Docker & Docker Compose setup
- Comprehensive test setup with pytest
- Code formatting with Black and isort
- Production-ready with Gunicorn
- Environment-based settings
- Custom user model
- Admin panel with Django Unfold
- API throttling and pagination
- CORS configuration
- Debug toolbar for development
The project includes a comprehensive Redis-based caching system with the following features:
-
Command Line Interface:
# Warm cache for specific models python manage.py cache_ops warm --models products.Product orders.Order # Clear all cache python manage.py cache_ops clear --force # Preload common queries python manage.py cache_ops preload # Show cache statistics python manage.py cache_ops stats # Show cache versions python manage.py cache_ops version
-
Cache Decorators:
from core.cache.decorators import cached_view, cached_method @api_controller('/products') class ProductController: @http_get('') @cached_view(timeout=300, key_prefix='products') def list_products(self): return Product.objects.all() @cached_method(timeout=300, key_prefix='product') def get_product_data(self, product_id): return Product.objects.get(id=product_id)
-
Versioned Cache:
from core.cache.versioning import VersionedCache # Create versioned cache for a namespace cache = VersionedCache('products') # Set and get data cache.set('featured', featured_products) featured = cache.get('featured') # Invalidate all cache for namespace cache.invalidate_all()
The system includes automatic cache warming for common queries:
-
Model Cache Warming:
from core.cache.warming import CacheWarmer warmer = CacheWarmer() warmer.warm_model(Product, chunk_size=100)
-
Query Preloading:
from core.cache.preload import CachePreloader preloader = CachePreloader() preloader.preload_products() # Preload product-related queries preloader.preload_all() # Preload all common queries
The Django admin includes a cache monitoring interface at /admin/cache-monitor/
with features:
- Cache statistics and metrics
- Cache version management
- Cache warming controls
- Clear cache by namespace
- Monitor cache usage
The system automatically invalidates cache when models are updated:
-
Signal Handlers:
from core.cache.signals import register_cache_signals # In apps.py def ready(self): register_cache_signals()
-
Related Model Invalidation:
- When a model is updated, related models' cache is automatically invalidated
- Handles both forward and reverse relationships
Add to your settings.py
:
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'PARSER_CLASS': 'redis.connection.HiredisParser',
'SOCKET_CONNECT_TIMEOUT': 5,
'SOCKET_TIMEOUT': 5,
'COMPRESSOR': 'django_redis.compressors.zlib.ZlibCompressor',
'IGNORE_EXCEPTIONS': True,
}
}
}
# Cache time to live in seconds
CACHE_TTL = 60 * 15 # 15 minutes
CACHE_KEY_PREFIX = 'ecommerce'
# Session backend
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
$ psql my_db # enter shell
$ createdb --username=USERNAME my_db # create db
$ dropdb my_db # drop db