A high-performance, enterprise-grade Django package for managing customer testimonials at scale. Built with Django REST Framework and optimized for applications handling millions of testimonials with thousands of concurrent users.
- โก Sub-100ms API responses with intelligent caching
- ๐ Optimized database queries with strategic indexing
- ๐ Background processing for emails and media
- ๐ Horizontal scaling ready with background task support
- ๐พ Smart caching strategies with automatic invalidation
- ๐ Complete testimonial management with approval workflows
- โญ Flexible rating systems (1-10 scale, configurable)
- ๐ท๏ธ Category organization with hierarchical support
- ๐ Rich media attachments (images, videos, audio, documents)
- ๐ฌ Response system for official company replies
- ๐ค Anonymous testimonials with privacy controls
- ๐ Smart caching for lightning-fast responses
- โก Background task processing with threading support
- ๐ Full-text search with optimized queries
- ๐ Real-time statistics with cached aggregations
- ๐ Bulk operations for efficient moderation
- ๐ Django REST Framework API with comprehensive endpoints
- ๐ Extensive documentation with examples
- ๐งช Comprehensive test suite with 95%+ coverage
- ๐ Internationalization ready with gettext support
- ๐ง Highly configurable with 25+ settings
- Python: 3.10+
- Django: 4.2+
- Django REST Framework: 3.14+
- Pillow: 10.0+ (for image handling)
- django-phonenumber-field: 7.0+
- django-filter: 23.2+
- django-background-tasks: For database-backed background task processing
pip install django-testimonialsAdd to your INSTALLED_APPS:
INSTALLED_APPS = [
# ... other apps
'rest_framework',
'django_filters',
'testimonials',
]python manage.py migrate testimonials# urls.py
from django.urls import path, include
urlpatterns = [
# ... other patterns
path('api/testimonials/', include('testimonials.api.urls')),
]from testimonials.models import Testimonial, TestimonialCategory
# Create a category
category = TestimonialCategory.objects.create(
name="Product Reviews",
description="Customer feedback on our products"
)
# Create a testimonial
testimonial = Testimonial.objects.create(
author_name="John Doe",
author_email="john@example.com",
content="This product exceeded my expectations!",
rating=5,
category=category
)
# Get published testimonials (uses caching automatically)
testimonials = Testimonial.objects.published()
featured = Testimonial.objects.featured()# settings.py
TESTIMONIALS_USE_CACHE = True
TESTIMONIALS_CACHE_TIMEOUT = 900 # 15 minutes
# Configure Django cache backend (Database Cache example)
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'testimonials_cache_table',
}
}Then run:
python manage.py createcachetable# settings.py
TESTIMONIALS_USE_BACKGROUND_TASKS = True
# Add django-background-tasks to INSTALLED_APPS
INSTALLED_APPS += ['background_task']
# Run migrations for background_task
# python manage.py migrateProcess tasks with:
python manage.py process_tasks# settings.py
TESTIMONIALS_NOTIFICATION_EMAIL = "admin@yoursite.com"
# Email backend configuration
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your-email@gmail.com'
EMAIL_HOST_PASSWORD = 'your-app-password'
DEFAULT_FROM_EMAIL = 'Your Site <noreply@yoursite.com>'โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ Frontend โ โ Django API โ โ Background โ
โ (React/Vue) โโโโโบโ (REST API) โโโโโบโ (Threads) โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ PostgreSQL โ โ Django Cache โ
โ (Database) โ โ (DB/LocMem) โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
-
GET /api/testimonials/- List testimonials (cached) -
POST /api/testimonials/- Create testimonial -
GET /api/testimonials/{id}/- Get testimonial details -
PUT/PATCH /api/testimonials/{id}/- Update testimonial -
DELETE /api/testimonials/{id}/- Delete testimonial
-
POST /api/testimonials/{id}/approve/- Approve testimonial -
POST /api/testimonials/{id}/reject/- Reject testimonial -
POST /api/testimonials/{id}/feature/- Feature testimonial -
POST /api/testimonials/bulk_action/- Bulk moderation
-
GET /api/categories/- List categories (cached) -
GET /api/categories/{id}/testimonials/- Category testimonials
-
GET /api/media/- List media files -
POST /api/testimonials/{id}/add_media/- Add media to testimonial
-
GET /api/testimonials/stats/- Get comprehensive statistics -
GET /api/testimonials/featured/- Get featured testimonials
// Fetch testimonials with caching
const response = await fetch('/api/testimonials/?page=1&page_size=10');
const data = await response.json();
// Create a new testimonial
const testimonial = await fetch('/api/testimonials/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrfToken
},
body: JSON.stringify({
author_name: 'Jane Smith',
content: 'Amazing service, highly recommend!',
rating: 5,
category_id: 1
})
});
// Get featured testimonials (cached)
const featured = await fetch('/api/testimonials/featured/');{% load static %}
<div class="testimonials-section">
<h2>What Our Customers Say</h2>
{% for testimonial in featured_testimonials %}
<div class="testimonial-card">
<div class="rating">
{% for i in "12345"|make_list %}
{% if forloop.counter <= testimonial.rating %}โญ{% endif %}
{% endfor %}
</div>
<blockquote>{{ testimonial.content }}</blockquote>
<cite>
{{ testimonial.author_name }}
{% if testimonial.company %}, {{ testimonial.company }}{% endif %}
</cite>
{% if testimonial.response %}
<div class="company-response">
<strong>Our Response:</strong> {{ testimonial.response }}
</div>
{% endif %}
</div>
{% endfor %}
</div># In your admin or management command
from testimonials.models import Testimonial
# Approve multiple testimonials
testimonial_ids = [1, 2, 3, 4, 5]
testimonials = Testimonial.objects.filter(id__in=testimonial_ids)
for t in testimonials:
t.approve(user=request.user)- ๐ก๏ธ Permission-based access with role-based moderation
- ๐ CSRF protection for all API endpoints
- ๐ Input validation with comprehensive sanitization
- ๐ซ Rate limiting for API endpoints
- ๐ค Anonymous submission with privacy controls
- ๐ง Email verification for author notifications
# All user-facing strings support translation
from django.utils.translation import gettext_lazy as _
# Example usage in templates
{% load i18n %}
{% trans "Submit your testimonial" %}
# Configure languages in settings.py
LANGUAGES = [
('en', _('English')),
('es', _('Spanish')),
('fr', _('French')),
# Add more languages
]| Operation | Without Optimization | With Optimization | Improvement |
|---|---|---|---|
| List API (100 items) | 250ms | 45ms | 82% faster |
| Detail API | 180ms | 25ms | 86% faster |
| Search queries | 400ms | 60ms | 85% faster |
| Bulk approve (1000) | 45 seconds | 3 seconds | 93% faster |
| Statistics calculation | 800ms | 50ms | 94% faster |
View all configuration options
# Performance & Caching
TESTIMONIALS_USE_CACHE = True
TESTIMONIALS_CACHE_TIMEOUT = 900
TESTIMONIALS_CACHE_KEY_PREFIX = "testimonials"
# Background Processing
TESTIMONIALS_USE_BACKGROUND_TASKS = True
TESTIMONIALS_EMAIL_RATE_LIMIT = 60
# File Handling
TESTIMONIALS_MAX_FILE_SIZE = 10 * 1024 * 1024 # 10MB
TESTIMONIALS_ENABLE_THUMBNAILS = True
TESTIMONIALS_THUMBNAIL_SIZES = {
'small': (150, 150),
'medium': (300, 300),
}
# Moderation
TESTIMONIALS_REQUIRE_APPROVAL = True
TESTIMONIALS_MODERATION_ROLES = ['content_manager']
TESTIMONIALS_ALLOW_ANONYMOUS = True
# Search & Pagination
TESTIMONIALS_SEARCH_MIN_LENGTH = 3
TESTIMONIALS_PAGINATION_SIZE = 10
TESTIMONIALS_SEARCH_RESULTS_LIMIT = 1000
# Features
TESTIMONIALS_ENABLE_CATEGORIES = True
TESTIMONIALS_ENABLE_MEDIA = True
TESTIMONIALS_ENABLE_DASHBOARD = True# Run the full test suite
python -m pytest
# Run with coverage
python -m pytest --cov=testimonials --cov-report=html
# Run specific test categories
python -m pytest testimonials/tests/test_api_views.py
python -m pytest testimonials/tests/test_model.py
python -m pytest testimonials/tests/test_serializers.pyWe welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Installation Guide - Detailed setup instructions
- Configuration - All configuration options
- API Reference - Complete API documentation
- Performance Guide - Optimization strategies
- Deployment Guide - Production deployment
- Customization - Extending the package
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Django and Django REST Framework
- Performance optimizations inspired by high-scale web applications
- Icons and design elements from the open-source community
โญ If this package helped you, please give it a star!