Django-Tagging - подсчитывать и упорядочивать верхние "теги" (есть ли более чистое решение для меня?)

Я использую Django-Tagging, и мне точно не нужно облако, я просто хочу ограниченный список самых популярных тегов, используемых в моих записях в блоге.

Используя следующее:

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

Он возвращает массив (обратите внимание, я использую Lorem Ipsum во время разработки):

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

Но затем, чтобы заказать и ограничить его, мне нужно сделать следующее:

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]

Есть ли более аккуратный способ сделать это? Я чувствую, что должно быть.

6 ответов

Решение

Джанго {% regroup %} тег шаблона может быть полезен для этого. Если предположить, tags находится в контексте вашего шаблона:

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

Если вы используете последнюю версию django, вы можете использовать агрегацию. http://docs.djangoproject.com/en/dev/topics/db/aggregation пример на этой странице.

Book.objects.annotate(num_authors=Count('authors')).order_by('num_authors')

Я нахожу следующий код сортировки немного более читабельным, чем тот, который вы написали. Конечно, это не устраняет проблему с источником, указанную abeyer

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

Если вам все равно нужно вытащить все теги, а ограничение на верхний n - это просто презентация, ответ Фрагсворта, вероятно, поможет. Если вы не используете оставшуюся часть тегов где-то еще, я бы сказал, что это действительно то, что должно происходить в запросе к базе данных... вы бы хотели сделать 'ORDER BY count DESC LIMIT n' на запрос, чтобы не тратить кучу тегов, которые вы не собираетесь использовать.

Однако, похоже, что django-теги жестко запрограммированы, чтобы всегда группировать / сортировать по идентификаторам и именам тегов. Я бы сказал, что правильное решение - подать сообщение об ошибке и получить доступ к API, который вернет вам первые n тегов.

Я использую raw sql для этого:

trends = Tag.objects.raw("select tagging_tag.id, count(object_id) as counter from tagging_tag left join tagging_taggeditem on tagging_tag.id = tagging_taggeditem.tag_id group by tagging_tag.id order by counter DESC limit 10")

Мой подход к получению топ-тегов в Django-Tagging таков:

top_tags = Tag.objects.annotate(num=Count('taggit_taggeditem_items')).order_by('-num')
Другие вопросы по тегам