CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-taggit

A reusable Django application for simple tagging with comprehensive manager and form support.

Pending
Overview
Eval results
Files

form-integration.mddocs/

Form Integration

Django forms integration for handling tag input and validation. Django-taggit provides form fields and widgets that make it easy to include tag functionality in Django forms with proper validation and user-friendly input methods.

Capabilities

TagField

A Django form field specifically designed for handling tag input as comma-separated values.

class TagField(forms.CharField):
    """
    Form field for handling tag input.
    
    Inherits from CharField and provides tag-specific validation
    and parsing of comma/space-separated tag input.
    """
    widget = TagWidget
    
    def clean(self, value):
        """
        Clean and validate tag input.
        
        Parameters:
        - value (str): Raw input string from form
        
        Returns:
        list: Parsed list of tag names
        
        Raises:
        ValidationError: If input format is invalid
        """
    
    def has_changed(self, initial_value, data_value):
        """
        Check if field value has changed.
        
        Parameters:
        - initial_value: Original tag list
        - data_value: New form input
        
        Returns:
        bool: True if tags have changed
        """
from django import forms
from taggit.forms import TagField

class ArticleForm(forms.Form):
    title = forms.CharField(max_length=200)
    content = forms.CharField(widget=forms.Textarea)
    tags = TagField()

# Usage in views
form = ArticleForm(data={'title': 'My Article', 'tags': 'python, django, tutorial'})
if form.is_valid():
    tags = form.cleaned_data['tags']  # ['python', 'django', 'tutorial']

Tag Widgets

Widget classes for rendering tag input fields in forms with appropriate formatting.

class TagWidget(forms.TextInput):
    """
    Text input widget for tag input.
    
    Provides formatting for tag display in forms, converting
    tag objects to comma-separated strings for editing.
    """

class TextareaTagWidget(forms.Textarea):
    """
    Textarea widget for tag input.
    
    Useful for cases where many tags are expected or
    longer tag names are common.
    """

class TagWidgetMixin:
    """
    Mixin providing tag formatting functionality.
    
    Can be used with any form widget to add tag formatting.
    """
    def format_value(self, value):
        """
        Format tag objects for display in forms.
        
        Parameters:
        - value: Tag objects or string value
        
        Returns:
        str: Formatted tag string for form display
        """

Admin Form Classes

Form classes specifically designed for admin interface functionality.

class MergeTagsForm(forms.Form):
    """
    Form for merging multiple tags into one.
    
    Used in the admin interface to combine duplicate
    or related tags into a single tag.
    """
    new_tag_name = forms.CharField(
        label="New Tag Name",
        max_length=100,
        help_text="Enter the name for the merged tag"
    )
    
    def clean_new_tag_name(self):
        """
        Validate the new tag name.
        
        Returns:
        str: Cleaned tag name
        """
from taggit.forms import TagField, TagWidget, TextareaTagWidget

class ArticleForm(forms.Form):
    title = forms.CharField(max_length=200)
    
    # Default text input widget
    tags = TagField()
    
    # Custom textarea widget for longer tag lists
    keywords = TagField(widget=TextareaTagWidget(attrs={'rows': 3}))
    
    # Custom styling
    categories = TagField(
        widget=TagWidget(attrs={
            'class': 'form-control',
            'placeholder': 'Enter tags separated by commas'
        })
    )

ModelForm Integration

Integration with Django ModelForms for seamless tag handling in model forms.

from django import forms
from taggit.forms import TagField
from myapp.models import Article

class ArticleModelForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ['title', 'content', 'tags']
        
    # TaggableManager fields are automatically handled
    # but can be customized if needed
    tags = TagField(
        required=False,
        help_text="Enter tags separated by commas"
    )

Custom Form Field Validation

Advanced validation patterns for tag input fields.

from django import forms
from django.core.exceptions import ValidationError
from taggit.forms import TagField

class CustomTagField(TagField):
    def clean(self, value):
        tags = super().clean(value)
        
        # Custom validation: limit number of tags
        if len(tags) > 10:
            raise ValidationError("Maximum 10 tags allowed")
        
        # Custom validation: tag length
        for tag in tags:
            if len(tag) > 50:
                raise ValidationError(f"Tag '{tag}' is too long (max 50 characters)")
        
        # Custom validation: forbidden words
        forbidden = ['spam', 'inappropriate']
        for tag in tags:
            if tag.lower() in forbidden:
                raise ValidationError(f"Tag '{tag}' is not allowed")
        
        return tags

class ArticleForm(forms.Form):
    title = forms.CharField(max_length=200)
    tags = CustomTagField()

Form Processing

Complete examples of processing forms with tag fields.

from django.shortcuts import render, redirect
from django.contrib import messages
from myapp.models import Article
from myapp.forms import ArticleForm

def create_article(request):
    if request.method == 'POST':
        form = ArticleForm(request.POST)
        if form.is_valid():
            # Create article
            article = Article.objects.create(
                title=form.cleaned_data['title'],
                content=form.cleaned_data['content']
            )
            
            # Add tags
            article.tags.set(form.cleaned_data['tags'])
            
            messages.success(request, 'Article created successfully!')
            return redirect('article_detail', pk=article.pk)
    else:
        form = ArticleForm()
    
    return render(request, 'articles/create.html', {'form': form})

def edit_article(request, pk):
    article = Article.objects.get(pk=pk)
    
    if request.method == 'POST':
        form = ArticleForm(request.POST)
        if form.is_valid():
            article.title = form.cleaned_data['title']
            article.content = form.cleaned_data['content']
            article.save()
            
            # Update tags
            article.tags.set(form.cleaned_data['tags'])
            
            return redirect('article_detail', pk=article.pk)
    else:
        # Pre-populate form with existing tags
        form = ArticleForm(initial={
            'title': article.title,
            'content': article.content,
            'tags': ', '.join(article.tags.names())
        })
    
    return render(request, 'articles/edit.html', {'form': form, 'article': article})

AJAX and Dynamic Forms

Implementing dynamic tag functionality with JavaScript and AJAX.

from django.http import JsonResponse
from django.views.decorators.http import require_GET
from taggit.models import Tag

@require_GET
def tag_autocomplete(request):
    """
    Provide tag suggestions for autocomplete functionality.
    """
    term = request.GET.get('term', '')
    if len(term) < 2:
        return JsonResponse({'suggestions': []})
    
    tags = Tag.objects.filter(
        name__icontains=term
    ).values_list('name', flat=True)[:10]
    
    return JsonResponse({'suggestions': list(tags)})

# In template (example JavaScript for autocomplete)
"""
<script>
$('#id_tags').autocomplete({
    source: "{% url 'tag_autocomplete' %}",
    minLength: 2
});
</script>
"""

Tag Input Parsing

Understanding how django-taggit parses different tag input formats.

from taggit.utils import parse_tags

# Different input formats and their parsed results
examples = [
    ('python, django, tutorial', ['django', 'python', 'tutorial']),
    ('python django tutorial', ['django', 'python', 'tutorial']),
    ('"web development", python, django', ['django', 'python', 'web development']),
    ('python,django,tutorial', ['django', 'python', 'tutorial']),
    ('"multi word tag", single', ['multi word tag', 'single']),
]

for input_str, expected in examples:
    result = parse_tags(input_str)
    print(f"Input: {input_str}")
    print(f"Parsed: {result}")
    print(f"Expected: {expected}")
    print("---")

Form Rendering and Templates

Template examples for rendering tag forms with proper styling.

<!-- Basic form rendering -->
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Save</button>
</form>

<!-- Custom form rendering -->
<form method="post">
    {% csrf_token %}
    <div class="form-group">
        <label for="{{ form.title.id_for_label }}">Title:</label>
        {{ form.title }}
        {% if form.title.errors %}
            <div class="error">{{ form.title.errors }}</div>
        {% endif %}
    </div>
    
    <div class="form-group">
        <label for="{{ form.tags.id_for_label }}">Tags:</label>
        {{ form.tags }}
        <small class="help-text">{{ form.tags.help_text }}</small>
        {% if form.tags.errors %}
            <div class="error">{{ form.tags.errors }}</div>
        {% endif %}
    </div>
    
    <button type="submit" class="btn btn-primary">Save Article</button>
</form>

<!-- With Bootstrap styling -->
<div class="mb-3">
    <label for="{{ form.tags.id_for_label }}" class="form-label">Tags</label>
    <input type="{{ form.tags.widget.input_type }}" 
           name="{{ form.tags.name }}" 
           value="{{ form.tags.value|default:'' }}"
           class="form-control{% if form.tags.errors %} is-invalid{% endif %}"
           id="{{ form.tags.id_for_label }}"
           placeholder="Enter tags separated by commas">
    {% if form.tags.help_text %}
        <div class="form-text">{{ form.tags.help_text }}</div>
    {% endif %}
    {% if form.tags.errors %}
        <div class="invalid-feedback">
            {% for error in form.tags.errors %}{{ error }}{% endfor %}
        </div>
    {% endif %}
</div>

Formsets and Inline Forms

Using tag fields in Django formsets and inline forms.

from django.forms import modelformset_factory
from myapp.models import Article

# Create formset with tag support
ArticleFormSet = modelformset_factory(
    Article, 
    fields=['title', 'content', 'tags'],
    extra=2
)

def bulk_edit_articles(request):
    queryset = Article.objects.filter(author=request.user)
    
    if request.method == 'POST':
        formset = ArticleFormSet(request.POST, queryset=queryset)
        if formset.is_valid():
            formset.save()
            return redirect('article_list')
    else:
        formset = ArticleFormSet(queryset=queryset)
    
    return render(request, 'articles/bulk_edit.html', {'formset': formset})

Install with Tessl CLI

npx tessl i tessl/pypi-django-taggit

docs

admin-interface.md

form-integration.md

index.md

model-integration.md

rest-framework.md

tag-operations.md

utilities-management.md

view-helpers.md

tile.json