Search code examples
djangodjango-querysetdjango-taggingdjango-select-related

Django tagging select_related


I using Django tagging project.

That is was very stable project. Working on django 1.3.

But i have a problem.

# in models.py
from tagging.fields import TagField
class Blog(models.Model):
     title = models.CharField(max_length = 300)
     content = models.TextField()
     tags = TagField()
     author = models.ForeignKey(User)

# in views.py
def blog_list(request):
    # I Want to use select related with tags
    blogs = Blog.objects.all().select_related("user", "tags") # ????
    ....

# in Templates
{% load tagging_tags %}
{% for blog in blogs %}
    {% tags_for_object blog as tags %}
    {{blog.title}}
    {% for tag in tags %}
        <a href="{% url tag_detail tag_id=tag.pk %}">{{tag}}</a>
    {% endfor %}
{% endfor %}

Solution

  • django-tagging uses a generic foreign key to your model, so you can't just use select_related.

    Something like this should do the trick though:

    from django.contrib.contenttypes.models import ContentType
    from collections import defaultdict
    from tagging.models import TaggedItem
    
    def populate_tags_for_queryset(queryset):
        ctype = ContentType.objects.get_for_model(queryset.model)
        tagitems = TaggedItem.objects.filter(
            content_type=ctype,
            object_id__in=queryset.values_list('pk', flat=True),
        )
        tagitems = tagitems.select_related('tag')
        tags_map = defaultdict(list)
        for tagitem in tagitems:
            tags_map[tagitem.object_id].append(tagitem.tag)
        for obj in queryset:
            obj.cached_tags = tags_map[obj.pk]