1👍
✅
The only thing missing is a .order_by()
[Django-doc] (yes, I know that is strange), this will force a GROUP BY
statement:
data['news_years'] = (
News.objects.annotate(year=ExtractYear('nw_publish'))
.values('year')
.annotate(total_entries=Count('year'))
.order_by()
)
as for using months, it might be better to truncate than extract, since then you still have a date object:
from django.db.models.functions import TruncMonth
data['news_years'] = (
News.objects.values(month=TruncMonth('nw_publish'))
.annotate(total_entries=Count('month'))
.order_by()
)
Showing a list of the posts after the click (how to get this list?)
You can make a path with the year and month with:
path(
'posts/<int:year>/<int:month>/', SomeListView.as_view(), name='posts-by-month'
),
then in the template you link to this with:
{% for news_year in news_years %}
<a href="{% url 'posts-by-month' news_year.month.year news_year.month.year %}">{{ news_year.month }} ({{ news_year.total_entries }})</a>
{% endfor %}
in the SomeListView
, you can then filter with:
class SomeListView(ListView):
model = News
def get_queryset(self, *args, **kwargs):
return (
super()
.get_queryset(*args, **kwargs)
.filter(
nw_publish__year=self.kwargs['year'],
nw_publish__month=self.kwargs['month'],
)
)
Source:stackexchange.com