Skip to content

Comprehensive Django utility package providing mixins, validators, decorators, and tools for enhanced Django development

License

Notifications You must be signed in to change notification settings

sageteamorg/django-sage-tools

Repository files navigation

πŸ› οΈ Django Sage Tools

Professional Django utilities for modern web development

PyPI version Python Support Django Support License: MIT

CI/CD codecov Code style: black Ruff

πŸ“š 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 authentication
  • AnonymousRequiredMixin - Restrict authenticated users
  • AccessMixin - Advanced permission handling

Performance & Caching

  • CacheControlMixin - Smart HTTP caching
  • NeverCacheMixin - Prevent caching when needed
  • HTTPHeaderMixin - Custom HTTP headers

User Experience

  • FormMessagesMixin - Automatic success/error messages
  • LocaleMixin - 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 timestamps
  • UUIDBaseModel - UUID primary keys for better security
  • BaseTitleSlugMixin - SEO-friendly URLs with auto-generated slugs

Specialized Models

  • AddressMixin - Complete address handling
  • RatingMixin - Star rating system
  • CommentMixin - 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 sizes
  • FileTypeValidator - Restrict file types

Data Validators

  • NameValidator - Validate person names
  • HalfPointIncrementValidator - 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 interfaces
  • LimitOneInstanceAdminMixin - Singleton pattern enforcement
  • AdminPrioritizeApp - 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 data
  • SessionEncryptor - Secure session data handling
  • DummyEncryptor - 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 BaseModel to UUIDBaseModel for clarity
  • CacheMixin split into CacheControlMixin and NeverCacheMixin
  • 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


🀝 Contributing

We ❀️ contributions! Here's how you can help:

Quick Contribute

  1. 🍴 Fork the repository
  2. 🌟 Star the project
  3. πŸ› Report bugs via issues
  4. πŸ’‘ Suggest features via discussions
  5. πŸ“ Improve documentation

Development Contribute

  1. Clone: git clone https://github.com/sageteamorg/django-sage-tools.git
  2. Setup: make dev-setup
  3. Code: Follow our style guide
  4. Test: make test
  5. 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


Made with ❀️ by the Sage Team

⬆️ Back to Top

About

Comprehensive Django utility package providing mixins, validators, decorators, and tools for enhanced Django development

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages