Я понимаю, что вы, вероятно, уже написали свой сырой SQL, но мне пришло в голову следующее, когда я увидел способ отображения ваших данных:
Если вы можете сделать это на уровне шаблона, вы можете стратегически использовать фильтр тегов и длины regroup .
Regroup берет «список похожих объектов», так что набор запросов может работать просто отлично, но в документах показан список словарей, поэтому я использовал значения здесь:
item_listing = Item.objects.values('category__name', 'donation__entry_date')
# use your favourite method to extract the year information into a key in item_listing
item_listing = ...
Теперь в шаблоне, что-то вроде:
<ul>
{% for year_group in item_listing %}
<li>{{ year_group.grouper }}
<ul>
{% regroup year_group.list by category__name as category_listing %}
{% for category_group in category_listing %}
<li>
Category: {{ category_group.grouper }}
Count: {{ category_group.list|length }}
</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
Я не уверен, хорошо ли встраивается тег перегруппировки (не пробовал). Кроме того, я понятия не имею, насколько хорошо выполняет перегруппировка, если у вас много данных, но опять же, всегда есть кеширование ...
Если вы решите использовать это, убедитесь, что вы обратили внимание на порядок, указанный в документах о перегруппировке.