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')