dj-flexi-tag

A flexible and efficient tagging system for Django models with service-only architecture.

Overview

Django Flexi Tag is a powerful tagging solution for Django projects built with a service-only architecture for maximum compatibility and composability. Unlike traditional tagging libraries that rely on complex many-to-many relationships, dj-flexi-tag uses PostgreSQL’s native JSON capabilities and a clean service layer for efficient and flexible tag management.

Key Features

  • πŸš€ Service-Only Architecture: Clean and composable design with full QuerySet compatibility

  • πŸ”„ Composable Filtering: Preserves existing QuerySet filters when adding tag filtering

  • ⚑ Easy Integration: Works seamlessly with Django REST Framework ViewSets

  • πŸ“¦ Flexible Tag Storage: Uses PostgreSQL JSONField for efficient and flexible tag storage

  • πŸ€– Automatic Model Generation: Generates auxiliary Tag models for your existing models

  • πŸ“Š Bulk Operations: Support for bulk tag operations on multiple objects

  • 🎯 Custom Exception Integration: Configurable base exception classes for seamless project integration

  • 🌐 Django Compatibility: Works across multiple Django versions (1.11 to 5.0)

  • 🐍 Python Compatibility: Supports Python 3.5+

Quick Start

  1. Install the package:

pip install dj-flexi-tag
  1. Add to your INSTALLED_APPS:

INSTALLED_APPS = [
    # ...
    'flexi_tag',
    # ...
]
  1. Make your model taggable:

from flexi_tag.utils.models import FlexiTagMixin

class Product(FlexiTagMixin):
    name = models.CharField(max_length=100)
    # other fields...
  1. Generate tag models:

python manage.py generate_tag_models
  1. Create and apply migrations:

python manage.py makemigrations
python manage.py migrate
  1. Use the service to add tags:

from flexi_tag.utils.service import TaggableService

# Add tags to instances
service = TaggableService()
service.add_tag(product, 'featured')
service.bulk_add_tags(product, ['sale', 'new-arrival'])

# Filter QuerySets by tags - preserves existing filters!
featured_products = service.filter_by_tag(Product.objects.filter(is_active=True), 'featured')
  1. Add tagging to your ViewSet (optional for REST API):

from rest_framework import viewsets
from flexi_tag.utils.views import TaggableViewSetMixin

class ProductViewSet(viewsets.ModelViewSet, TaggableViewSetMixin):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

Now you can use the tagging API to add, remove, and manage tags on your models!

API Usage Example

Add a tag to an object:

POST /api/products/1/add_tag/
{"key": "featured"}

Add multiple tags:

POST /api/products/1/bulk_add_tag/
{"keys": ["sale", "new-arrival"]}

Remove a tag:

POST /api/products/1/remove_tag/
{"key": "featured"}