views:

237

answers:

4

I'm using Django-Tagging, and I don't exactly need a cloud, I just want a limited list of the most popular tags used in my blog entries.

Using the following:

[(tag.name, int(tag.count)) for tag in Tag.objects.usage_for_model(Post, counts=True)]

It returns an array (note I'm using Lorem Ipsum while I develop):

[(u'deposit', 5), (u'escorol', 1), (u'gratuitous', 8), (u'marquee', 2)]

But then to order and limit it I need to then do this:

sorted([(tag.name, int(tag.count)) for tag in Tag.objects.usage_for_model(Post, counts=True)], key=lambda k:k[1], reverse=True)[:10]

Is there a neater way to do this? I feel like there must be.

+2  A: 

Django's {% regroup %} template tag might be useful for this. Assuming tags is in the context of your template:

{% regroup tags|dictsort:"count" by count as sorted_tags %}
...
{% for count in sorted_tags %}
...
    {% for tag in count %}
    ...
    {% endfor %}
{% endfor %}
Fragsworth
A: 

If you need to pull all the tags anyway, and the limit to the top n is simply a presentation thing, Fragsworth's answer is probably the way to go. If you aren't using the remainder of the tags somewhere else, I'd argue that this is really something that should be happening in the database query...you would want to be doing an 'ORDER BY count DESC LIMIT n' on the query to avoid pulling a bunch of tags that you aren't going to use.

However, it appears that django-tagging is hard coded to always group/sort by tag ids and names. I'd say the right solution is to file a bug against that, and get an api exposed that will give you back the top n tags.

abeyer
+3  A: 

If you are using the latest version of django, you could use aggregation. http://docs.djangoproject.com/en/dev/topics/db/aggregation an example on that page ..

Book.objects.annotate(num_authors=Count('authors')).order_by('num_authors')
Mayuresh
this is a great approach
Keith Fitzgerald
+1  A: 

I find the following sorting code a bit more readable than the one you wrote. Of course it doesn't remove the source problem stated by abeyer

import operator
tags = Tag.objects.usage_for_model(Post, counts=True)
tags.sort(key=operator.attrgetter('count'), reverse=True)
cool works perfectly
soField