3

I could not find an answer for this.. So here my question. For a new project i'd like to use django-taggit.

Does someone have a suggestion on how to create a tag-cloud based on the current queryset?

The desired behavior is to 'start' with an unfiltered list - then allow narrowing town the results with applying filters and tags. At the beginning the tag-cloud shows e.g. the 50 most common tags. After choosing a tag (or other criteria) the tag-cloud should only display the remaining possibilities.

I know that django-tagging offers Tag.objects.usage_for_queryset() for this situation. But I would prefer to use '-taggit' over '-tagging'.

ohrstrom
  • 2,890
  • 2
  • 20
  • 34

4 Answers4

4

django-taggit-templatetags appears to be the 'go-to' place for a tagcloud for django-taggit.

It doesn't appear to handle querysets though. :(

So, I've added:

@register.inclusion_tag('taggit_templatetags/tagcloud_include_qs.html')
def include_tagcloud_qs(queryset):
    try:
        queryset = queryset.annotate(num_times=Count('taggeditem_items'))
    except FieldError:
        queryset = queryset.annotate(num_times=Count('taggit_taggeditem_items'))

    num_times = queryset.values_list('num_times', flat=True)

    weight_fun = get_weight_fun(T_MIN, T_MAX, min(num_times), max(num_times))
    queryset = queryset.order_by('name')
    for tag in queryset:
        tag.weight = weight_fun(tag.num_times)

    return {"tags": queryset}

to

templatetags/taggit_extras.py

And this to a new file at taggit_templatetags/tagcloud_include_qs.html

<div>
{% for tag in tags %}
<font size={{tag.weight|floatformat:0}}>{{tag}}</font> 
{% endfor %}
</div>

I'm using it like this in my templates:

{% include_tagcloud_qs my_queryset %}

I haven't spent much time looking at the django-taggit-templatetags code, so feel free to update this with a better solution!

PS:

I'm getting a queryset in my view like this:

my_queryset = Tag.objects.filter(foo__bar=baz).distinct()
Steven Keith
  • 1,789
  • 15
  • 23
2

This answer shows how to build a tag cloud. You'd create a queryset in your view according to your parameters, generate a dictionary, and render it in your templates as shown in that answer.

Community
  • 1
  • 1
Joe Mornin
  • 8,766
  • 18
  • 57
  • 82
0

I would suggest using django-tagging. It is well documented. I have created tag clouds with it. You can access tag clouds via model, model instance, etc via template tags that are easy to load. This is a little hackish but using the .counts method you can hack up some css to increase the size of each font as you would see in a real tag cloud. Django-tagging actually excels in this area as it has a default template tag with formatting options for everything you have described.

eusid
  • 769
  • 2
  • 6
  • 18
  • Yes, maybe I'll have to go with django-tagging. It is just that i use *-taggit in a lot of other projects. And that the only missing thing (usage_for_queryset) seems to be rather buggy in *-tagging: http://goo.gl/gjmNV – ohrstrom May 28 '12 at 13:57
  • 1
    I assume since you are looking for a queryset useage then you are wanting to retrieve tags off a variety of objects and assemble them in one place. If this is the case I would edit my question to reflect that and possibly include the views and models you are using. Here is the queryset api documentation https://docs.djangoproject.com/en/dev/ref/models/querysets/ . A template tag may help. do note that having ListView.as_view(model=Author) is the same as defining queryset Author.objects.all(). Which when your in a model instance you gain access to Model.entry_set – eusid May 28 '12 at 23:15
0

I've added a TagBase.get_for() function in https://github.com/twig/django-taggit/commit/42cd4e04f00496103f295c0afd8297074be50dcf

This basically fetches the Tags used for a given queryset, and from there you can do what you need to do.

twig
  • 4,034
  • 5
  • 37
  • 47