每月的项目数在 CreateView 中有效,但在 TemplateView 中无效

Number of Items per month works in CreateView, but not in TemplateView

我的目标:每月显示在我的模板中的项目数,即:2021 年 5 月 - 5,2021 年 6 月 - 10,2021 年 9 月 - 3 , 2021 年 10 月 - 2, 等等

我所做的。 我首先创建了一个测试项目,我的索引视图继承自 CreateView(表单需要它)。一切正常。 但是,在我的主项目中,我的 IndexView 是从 django 的 TemplateView 继承的,并且使用相同的代码显示如下: Sep 2021 - 1, Sep 2021 - 1, Oct 2021 - 1, Oct 2021 - 1, Oct 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(注意上下文['per_month']行)

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 %}

输出:

Aug 2021 - 2 Sep 2021 - 1 Oct 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(如果问题是 DatetimeField,而不是 DateField),但没有帮助。

views.py(相同上下文['per_month']行)

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(同上)

输出:

Aug 2021 -1 Aug 2021 -1 Oct 2021 - 1 Oct 2021 - 1 Oct 2021 - 1 Oct 2021 - 1

您应该添加 .order_by(…) 以强制分组依据,因此:

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