Comprehensive Django utility package providing mixins, validators, decorators, and tools for enhanced Django development
Project description
๐ ๏ธ Django Sage Tools
Professional Django utilities for modern web development
๐ Documentation | ๐ Quick Start | ๐ก Examples | ๐ค Contributing | ๐ Changelog
๐ Why Django Sage Tools?
Transform your Django development with a comprehensive suite of production-ready utilities, mixins, and tools. Designed by Django experts for Django developers who demand quality, performance, and maintainability.
โจ Key Highlights
๐ฏ Production Ready - Battle-tested in real-world applications
โก Performance Focused - Optimized for speed and efficiency
๐ง Developer Friendly - Intuitive APIs with comprehensive documentation
๐ก๏ธ Type Safe - Full type hints support with mypy compatibility
๐ Modern Django - Supports Django 4.2+ with async capabilities
๐ฑ Responsive Design - Admin tools that work beautifully on all devices
๐ Quick Start
Installation
# Using pip
pip install django-sage-tools
# Using Poetry (recommended)
poetry add django-sage-tools
# Using pipenv
pipenv install django-sage-tools
Basic Setup
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
# ... other apps
'sage_tools', # Add this line
]
# Optional: Add configuration
SAGE_TOOLS = {
'AUTO_SLUGIFY_ENABLED': True,
'CLEANUP_DELETE_FILES': True,
}
Your First Sage Tool
# models.py
from django.db import models
from sage_tools.mixins.models.base import TimeStampMixin, UUIDBaseModel
class Article(TimeStampMixin, UUIDBaseModel):
title = models.CharField(max_length=200)
content = models.TextField()
def __str__(self):
return self.title
# views.py
from django.views.generic import ListView
from sage_tools.mixins.views.access import LoginRequiredMixin
from sage_tools.mixins.views.cache import CacheControlMixin
class ArticleListView(LoginRequiredMixin, CacheControlMixin, ListView):
model = Article
template_name = 'articles/list.html'
cache_timeout = 300 # 5 minutes
That's it! ๐ Your model now has UUID primary keys, automatic timestamps, and your view requires authentication with smart caching.
๐ฆ Core Features
๐ญ View Mixins - Supercharge your class-based views
Access Control
LoginRequiredMixin- Ensure user authenticationAnonymousRequiredMixin- Restrict authenticated usersAccessMixin- Advanced permission handling
Performance & Caching
CacheControlMixin- Smart HTTP cachingNeverCacheMixin- Prevent caching when neededHTTPHeaderMixin- Custom HTTP headers
User Experience
FormMessagesMixin- Automatic success/error messagesLocaleMixin- Multi-language support
from sage_tools.mixins.views import (
LoginRequiredMixin, CacheControlMixin, FormMessagesMixin
)
class ProductCreateView(LoginRequiredMixin, FormMessagesMixin, CreateView):
model = Product
template_name = 'products/create.html'
success_message = "Product created successfully! ๐"
error_message = "Please correct the errors below."
๐๏ธ Model Mixins - Enhance your Django models
Base Models
TimeStampMixin- Automatic created/modified timestampsUUIDBaseModel- UUID primary keys for better securityBaseTitleSlugMixin- SEO-friendly URLs with auto-generated slugs
Specialized Models
AddressMixin- Complete address handlingRatingMixin- Star rating systemCommentMixin- User comments and reviews
from sage_tools.mixins.models import TimeStampMixin, UUIDBaseModel, RatingMixin
class Restaurant(TimeStampMixin, UUIDBaseModel, RatingMixin):
name = models.CharField(max_length=100)
cuisine = models.CharField(max_length=50)
# Automatically includes: id (UUID), created_at, modified_at, rating fields
โก Validators - Bulletproof data validation
File Validators
FileSizeValidator- Control upload sizesFileTypeValidator- Restrict file types
Data Validators
NameValidator- Validate person namesHalfPointIncrementValidator- Rating validation (0.5, 1.0, 1.5...)NumeralValidator- Number format validation
from sage_tools.validators import FileSizeValidator, NameValidator
class UserProfile(models.Model):
name = models.CharField(
max_length=100,
validators=[NameValidator()]
)
avatar = models.ImageField(
upload_to='avatars/',
validators=[FileSizeValidator(max_size=5*1024*1024)] # 5MB limit
)
๐ง Admin Tools - Professional Django admin experience
Admin Mixins
ReadOnlyAdmin- View-only admin interfacesLimitOneInstanceAdminMixin- Singleton pattern enforcementAdminPrioritizeApp- Customize admin app ordering
from django.contrib import admin
from sage_tools.mixins.admins import LimitOneInstanceAdminMixin
@admin.register(SiteConfiguration)
class SiteConfigAdmin(LimitOneInstanceAdminMixin, admin.ModelAdmin):
# Only allows one site configuration instance
pass
๐ Security & Encryption - Keep your data safe
Encryption Tools
FernetEncryptor- Symmetric encryption for sensitive dataSessionEncryptor- Secure session data handlingDummyEncryptor- Testing and development placeholder
Security Utilities
- CSRF handling utilities
- Secure file upload handling
- Session security enhancements
from sage_tools.encryptors import FernetEncryptor
# settings.py
FERNET_SECRET_KEY = "your-secret-key-here"
# Usage
encryptor = FernetEncryptor()
encrypted_data = encryptor.encrypt("sensitive information")
decrypted_data = encryptor.decrypt(encrypted_data)
๐ก Examples
๐ช E-commerce Product Model
from django.db import models
from sage_tools.mixins.models import (
TimeStampMixin, UUIDBaseModel, RatingMixin
)
from sage_tools.validators import FileSizeValidator
class Product(TimeStampMixin, UUIDBaseModel, RatingMixin):
name = models.CharField(max_length=200)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
image = models.ImageField(
upload_to='products/',
validators=[FileSizeValidator(max_size=2*1024*1024)] # 2MB
)
is_active = models.BooleanField(default=True)
class Meta:
ordering = ['-created_at']
def __str__(self):
return f"{self.name} - ${self.price}"
๐ Protected Admin Dashboard
from django.views.generic import TemplateView
from sage_tools.mixins.views import (
LoginRequiredMixin, CacheControlMixin, AccessMixin
)
class AdminDashboardView(LoginRequiredMixin, AccessMixin, CacheControlMixin, TemplateView):
template_name = 'admin/dashboard.html'
cache_timeout = 600 # 10 minutes
permission_required = 'auth.view_user'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
'total_users': User.objects.count(),
'active_sessions': Session.objects.filter(expire_date__gte=timezone.now()).count(),
'recent_orders': Order.objects.filter(created_at__gte=timezone.now() - timedelta(days=7)),
})
return context
๐จ Smart Form with Auto-Messages
from django.views.generic import CreateView
from sage_tools.mixins.views import FormMessagesMixin
from sage_tools.mixins.forms import UserFormMixin
class ContactFormView(FormMessagesMixin, UserFormMixin, CreateView):
model = Contact
fields = ['name', 'email', 'subject', 'message']
template_name = 'contact/form.html'
success_url = '/contact/thank-you/'
# Auto-injected messages
success_message = "Thank you! We'll get back to you soon. ๐ง"
error_message = "Please check the form for errors."
def form_valid(self, form):
# Auto-assigns current user if available
return super().form_valid(form)
๐ง Configuration
Optional Settings
# settings.py
SAGE_TOOLS = {
# Encryption
'FERNET_SECRET_KEY': env('FERNET_SECRET_KEY'),
# File handling
'CLEANUP_DELETE_FILES': True,
'MAX_UPLOAD_SIZE': 10 * 1024 * 1024, # 10MB
# Slugs
'AUTO_SLUGIFY_ENABLED': True,
'SLUG_SEPARATOR': '-',
# Caching
'DEFAULT_CACHE_TIMEOUT': 300, # 5 minutes
# Admin
'ADMIN_REORDER_APPS': True,
}
Environment Variables
# .env
FERNET_SECRET_KEY=your-32-character-base64-key-here
DJANGO_DEBUG=False
DJANGO_SECRET_KEY=your-django-secret-key
๐งช Testing
# Run tests
python -m pytest
# With coverage
python -m pytest --cov=sage_tools
# Specific test module
python -m pytest tests/test_mixins.py -v
Test Your Integration
# test_integration.py
from django.test import TestCase
from sage_tools.mixins.models import TimeStampMixin, UUIDBaseModel
class TestSageToolsIntegration(TestCase):
def test_model_mixins(self):
# Test your models with Sage Tools mixins
article = Article.objects.create(title="Test", content="Content")
# UUID primary key
self.assertIsInstance(article.id, UUID)
# Automatic timestamps
self.assertIsNotNone(article.created_at)
self.assertIsNotNone(article.modified_at)
๐ Performance Tips
Database Optimizations
# Use select_related with TimeStampMixin models
articles = Article.objects.select_related('author').prefetch_related('tags')
# Leverage UUID indexes
class Meta:
indexes = [
models.Index(fields=['created_at']),
models.Index(fields=['id', 'created_at']),
]
Caching Best Practices
# Smart cache invalidation
class ArticleListView(CacheControlMixin, ListView):
cache_timeout = 600 # 10 minutes
cache_key_prefix = 'articles'
def get_cache_key(self):
return f"{self.cache_key_prefix}:{self.request.user.id}"
๐ก๏ธ Security Considerations
- ๐ Use UUIDs for public-facing model IDs
- ๐ซ Validate uploads with FileSizeValidator
- ๐ Encrypt sensitive data with FernetEncryptor
- โก Rate limit admin actions with custom mixins
- ๐ก๏ธ Sanitize user input with built-in validators
๐ Migration Guide
From v0.2.x to v0.3.x
# Old way
from sage_tools.utils import some_function
# New way (v0.3.x)
from sage_tools import some_function
Breaking Changes
- Renamed
BaseModeltoUUIDBaseModelfor clarity CacheMixinsplit intoCacheControlMixinandNeverCacheMixin- Updated minimum Django version to 4.2
๐งฉ Compatibility
| Component | Version Support |
|---|---|
| Python | 3.8, 3.9, 3.10, 3.11, 3.12 |
| Django | 4.2, 5.0, 5.1, 5.2 |
| Database | PostgreSQL, MySQL, SQLite |
| Cache | Redis, Memcached, Database |
๐ ๏ธ Development
Local Setup
# Clone repository
git clone https://github.com/sageteamorg/django-sage-tools.git
cd django-sage-tools
# Install dependencies
poetry install
# Run quality checks
make format lint test
# Run pre-commit hooks
make pre-commit
Available Commands
make help # Show all available commands
make install # Install dependencies
make test # Run tests
make format # Format code
make lint # Run linting
make build # Build package
make publish-test # Publish to Test PyPI
make publish # Publish to PyPI
๐ Troubleshooting
Common Issues
Import Errors
# โ Wrong
from sage_tools.mixins import TimeStampMixin
# โ
Correct
from sage_tools.mixins.models import TimeStampMixin
# or
from sage_tools import TimeStampMixin
UUID Field Issues
# If you get UUID field errors, ensure:
# 1. Migrations are up to date
python manage.py makemigrations
python manage.py migrate
# 2. Database supports UUIDs (PostgreSQL recommended)
Cache Not Working
# Ensure cache backend is configured
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/1',
}
}
๐ Success Stories
"Django Sage Tools transformed our development workflow. The mixins are incredibly powerful and the documentation is top-notch!"
โ Sarah Chen, Lead Developer at TechCorp
"We reduced our boilerplate code by 60% using Sage Tools. The UUID and timestamp mixins alone saved us weeks of development."
โ Marcus Rodriguez, CTO at StartupXYZ
๐ Learn More
- ๐ Full Documentation
- ๐ฅ Video Tutorials
- ๐ก Best Practices Guide
- ๐ฏ Migration Guide
๐ค Contributing
We โค๏ธ contributions! Here's how you can help:
Quick Contribute
- ๐ด Fork the repository
- ๐ Star the project
- ๐ Report bugs via issues
- ๐ก Suggest features via discussions
- ๐ Improve documentation
Development Contribute
- Clone:
git clone https://github.com/sageteamorg/django-sage-tools.git - Setup:
make dev-setup - Code: Follow our style guide
- Test:
make test - Submit: Create a pull request
Contributors
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
- ๐ Django Team - For the amazing framework
- ๐๏ธ Python Community - For the incredible ecosystem
- ๐จ Contributors - For making this project awesome
- โ Coffee - For fueling late-night coding sessions
๐ Support
- ๐ Bug Reports: GitHub Issues
- ๐ฌ Discussions: GitHub Discussions
- ๐ง Email: sepehr@sageteam.org
- ๐ฆ Twitter: @sageteamorg
Made with โค๏ธ by the Sage Team
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_sage_tools-2.0.0.tar.gz.
File metadata
- Download URL: django_sage_tools-2.0.0.tar.gz
- Upload date:
- Size: 60.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.3 CPython/3.13.3 Windows/11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
576cc665fa594983f092e9c41f4456e698c22f0c96b7c5dfcbff2c27e74377d7
|
|
| MD5 |
644c17f9e91875a055decbf3c01bfe6f
|
|
| BLAKE2b-256 |
7088fa282ce5e7f35b9fc15505adc065baffd196b0602979892a7275041c1699
|
File details
Details for the file django_sage_tools-2.0.0-py3-none-any.whl.
File metadata
- Download URL: django_sage_tools-2.0.0-py3-none-any.whl
- Upload date:
- Size: 80.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.1.3 CPython/3.13.3 Windows/11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62915687ebdef1f7320b08acfa5a65be0bb48c68cd9070d9b8ce42552bbb2ba3
|
|
| MD5 |
02ea4cc99ba98211b7c390667e423ddc
|
|
| BLAKE2b-256 |
b2f3a48819234315dac6413efe3e28beb4e1108e855d0eb58b54eba1099644ca
|