Как составить список объектов с одинаковой датой?
Я хочу перечислить все элементы в моем шаблоне, но я хочу перечислить элементы под одним годом. Например, под заголовком 2021 года должны быть перечислены объекты модели для этого года. Названия годов должны появляться динамически. Как я могу это сделать?
views.py
def press_list(request):
press_contents = PressContent.objects.all().order_by('-date')
context = {
'press_contents': press_contents
}
return render(request, "press_list.html", context)
models.py
class PressContent(models.Model):
label = models.CharField(max_length=500)
url = models.URLField(max_length=500)
date = models.DateTimeField(blank=True, null=True)
press_list.html
{% for press in press_contents %}
<div class="card" style="width: 18rem; margin:15px">
<div class="card-header">
{{ press.date.year }}
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item"><a href="{{ press.url }}">{{ press.label }}</a></li>
# Other objects from this year should come here.
</ul>
</div>
{% endfor %}
Для ясности: 2021
- пока 1
- bj 2 2020
- obj 3 .
- bj 4 ... ...
Вы можете работать с тегом шаблона {% regroup … by … %}
[Django-doc]:
{% regroup press_contents by year as press %}
{% for pressyear in press_contents %}
<div class="card" style="width: 18rem; margin:15px">
<div class="card-header">
{{ press.date.grouper }}
</div>
<ul class="list-group list-group-flush">
{% for press in pressyear.list %}
<li class="list-group-item"><a href="{{ press.url }}">{{ press.label }}</a></li>
# Other objects from this year should come here.
{% endfor %}
</ul>
</div>
{% endfor %}
Если вы можете позволить себе преобразовать queryset в список объектов, то вы можете использовать встроенный фильтр шаблона regroup (кажется, я никогда не использовал его).
Другим подходом может быть написание функции-генератора на языке python и передача ей контекста, который будет итерироваться шаблоном. Это позволяет избежать проблем с потреблением ресурсов, когда набор запросов состоит из большого количества объектов. Что-то вроде
def year_grouper():
qs = PressContent.objects.all().order_by('-date')
last_object_year = 1000000000
for obj in qs:
obj.year_changed = ( obj.date.year != last_object_year )
yield obj
last_object_year = obj.date.year
и
{% for obj in year_grouper %}
{% if obj.year_changed %}
... year header, etc.
{% endif %}
... display obj
{% endfor %}