Использование эквивалента тега django regroup в python
У меня есть проект, построенный на django, в котором я использую шаблонизатор django. Я хочу переключить фронтенд с шаблонизатора django на reactjs. Все работает достаточно хорошо с использованием шаблонизатора django. Я гуглил и переполнял стек везде, но не нашел решения моей проблемы. Вот что я сделал, используя шаблонизатор django (все работает хорошо):
# models.py
class Post(models.Model):
...
publish = models.DateTimeField(
default=timezone.now,
verbose_name=("Publication date"),
)
...
Мой templatetag выглядит следующим образом:
# blog_tags.py
@register.inclusion_tag('blog/month_links_snippet.html')
def render_month_links():
all_posts = Post.published.dates('publish', 'month', order='DESC')
return {'all_posts': all_posts,}
Мой файл шаблона выглядит следующим образом:
# blog/month_links_snippet.html
{% regroup all_posts by year as dates_by_year %}
<div class="sidebar">
<ul class="active list-unstyled">
{% for month in dates_by_year %}
<li id="year{{ month.grouper }}"{% if forloop.first %} class="active"{% endif %}>
<h2 style="font-size: 18px"><a href="{% url 'blog:archive-year' month.grouper %}">{{ month.grouper }}</a> <i class="collapsing-icon fa fa-plus"></i></h2>
<div class="collapsing-content">
<ul class="list-unstyled">
{% for d in month.list %}
<li><a href="{% url 'blog:archive_month_numeric' d|date:"Y" d|date:"n" %}">{{ d|date:"F Y" }}</a></li>
{% endfor %}
</ul>
</div>
</li>
{% endfor %}
</ul>
</div>
Все работает так, как ожидалось. Посмотрите:
Как я могу достичь этого, используя django rest framework?
Помните, что эти данные позже будут потребляться reactjs.
Вот методы, которые я пробовал до сих пор с DRF
Метод 1
# models.py
class Post(models.Model):
...
publish = models.DateTimeField(
default=timezone.now,
verbose_name=("Publication date"),
)
...
def date(self):
return self.publish.strftime("%Y-%m-%d")
Мой модуль сериализаторов выглядит следующим образом:
# serializers.py
class PostArchiveSidebarSerializer(serializers.ModelSerializer):
publish = serializers.DateTimeField(format="%Y")
date= serializers.SerializerMethodField(source="date")
class Meta:
model = Post
fields = ["publish", "date"]
def get_date(self, obj):
return obj.date()
Мой модуль представлений выглядит следующим образом:
from itertools import groupby
from operator import itemgetter
@api_view(["GET"])
def year_month_archive(request):
# published = PublishedManager() my custom manager.
posts = Post.published.filter(status='published').order_by('-publish')
serializer = PostArchiveSidebarSerializer(posts, many=True)
grouped = groupby(serializer.data, itemgetter('date'))
new_data = {k:next(v) for k, v in grouped}
# I use the next() func to make the month unique for a specific year
return Response(new_data)
Выход метода 1
{
"2021-08-31": {
"publish": "2021",
"date": "2021-08-31"
},
"2020-12-05": {
"publish": "2020",
"date": "2020-12-05"
},
"2020-05-17": {
"publish": "2020",
"date": "2020-05-17"
},
"2020-04-06": {
"publish": "2020",
"date": "2020-04-06"
},
"2020-03-12": {
"publish": "2020",
"date": "2020-03-12"
},
"2020-02-09": {
"publish": "2020",
"date": "2020-02-09"
},
"2019-09-13": {
"publish": "2019",
"date": "2019-09-13"
}
}
Метод 2
# models.py
class Post(models.Model):
...
publish = models.DateTimeField(
default=timezone.now,
verbose_name=("Publication date"),
)
...
Здесь не нужны сериализаторы
# views.py
from collections import defaultdict, Counter
from django.template.defaultfilters import date
@api_view(["GET"])
def year_month_archive(request):
year_frequency = defaultdict(int)
all_posts = Post.published.dates("publish", "month", order="DESC")
for year in all_posts:
format_month = date(year, 'F Y')
year_frequency[year.year] += 1
year_frequency[format_month] += 1
count_year = list(Counter(year_frequency))
return Response({'archive': count_year})
Выход метода 2
{
"archive": [
2021,
"August 2021",
2020,
"December 2020",
"May 2020",
"April 2020",
"March 2020",
"February 2020",
2019,
"September 2019"
]
}
Моя цель - создать аккордеон с годом 2021
в качестве заголовка и August 2021
в качестве содержимого.
Любая помощь будет высоко оценена.
Заранее спасибо
Это мой первый вопрос здесь 😁