Количество элементов в месяц работает в CreateView, но не в TemplateView

#python #django #django-views #django-templates #django-orm

Вопрос:

Моя цель: получить количество элементов в месяц, отображаемых в моем шаблоне, т. е.: Май 2021 — 5, июнь 2021 — 10, сентябрь 2021 — 3, октябрь 2021 — 2 и т. Д

что я сделал. Я сначала создал тестовый проект и мое представление индекса, унаследованное от CreateView (это необходимо для формы). Все работало нормально. Однако в моем основном проекте мое представление индекса унаследовано от представления шаблонов django, и с тем же кодом оно отображается следующим образом: Сентябрь 2021 — 1, сентябрь 2021 — 1, Октябрь 2021 — 1, Октябрь 2021 — 1, Октябрь 2021 — 1, Октябрь 2021-1, Октябрь 2021-1… вы поняли, в чем дело. Поэтому по какой-то причине он рассматривает каждый пункт как отдельную дату, не пытаясь их агрегировать.

Таким образом, причиной различий должно быть наследование от разных представлений в django, однако в моем основном проекте я не могу сделать так, чтобы мое представление индекса наследовалось от CreateView. Кроме того, я все еще новичок в Django и был бы очень признателен за любую помощь, которую я могу получить. Мне потребовалось много усилий, чтобы понять это до этого момента.

Вот мой рабочий код (в тестовом проекте):

models.py

 class Movie(models.Model):
    title = models.CharField('Movie name', max_length=100)
    gross = models.IntegerField('Gross', help_text='Worldwide, in dollars.')
    release_date = models.DateField('Date of release', blank=True, null=True)

    def __str__(self):
        return self.title
 

views.py (обратите внимание на контекстную строку[«за месяц»])

 class IndexView(CreateView):
    form_class = CreateMovieForm
    template_name = 'home/index.html'
    success_url = '/'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # per_month = queryset of dictionaries: month   number of movies in each month
        context['per_month'] = Movie.objects.annotate(
            month=TruncMonth('release_date')).values('month').annotate(c=Count('id')).values('month', 'c')
        context['movies'] = Movie.objects.all()
        return context
 

forms.py (не уверен, что это уместно здесь, но на всякий случай)

 class CreateMovieForm(forms.ModelForm):
    class Meta:
        model = Movie
        fields = '__all__'

        widgets = {'release_date': DateInput(attrs={'value': timezone.now().date})}
 

index.html

 {% for month in per_month %}
    <ul>
        <li>
            {{ month.month|date:"M Y" }} - {{ month.c }}
        </li>
    </ul>
{% endfor %}
 

Выход:

Август 2021 — 2 сентября 2021 — 1 октября 2021 — 3

Вот мой нерабочий код (основной проект):

models.py

 class Item(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    assigned_to = models.ManyToManyField(User)
    date_posted = models.DateTimeField(auto_now_add=True)
    deadline_date = models.DateField(null=True)
 

Примечание: Я попытался поэкспериментировать с обоими: date_posted и deadline_date (в случае, если проблема заключалась в поле времени даты, а не в поле даты), но это не помогло.

views.py (тот же контекст [строка «за месяц»])

 class IndexView(LoginRequiredMixin, TemplateView):
    template_name = 'bugtracker/main.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # per_month = queryset of dictionaries: month   number of movies in each month
        context['per_month'] = Item.objects.annotate(
            month=TruncMonth('date_posted')).values('month').annotate(c=Count('id')).values('month', 'c')
 

index.html (то же, что и выше)

Выход:

Авг 2021 -1 Авг 2021 -1 Окт 2021 — 1 Окт 2021 — 1 Окт 2021 — 1 Окт 2021 — 1

Ответ №1:

Вы должны добавить a .order_by(…) в группировку по силе, поэтому:

 context['per_month'] = Item.objects.values(
    month=TruncMonth('date_posted')
).annotate(c=Count('id')).order_by('month') 

Комментарии:

1. Ну, я буду… это действительно так. Вы, сэр, спасаете мне жизнь. Теперь в этом так много смысла. Большое вам спасибо!