我有一个用下面的Chart JS库创建的图表:

Chart JS

我的Models.py如下:

class Organization(models.Model):
    name = models.CharField(max_length=250, unique=True)

    def __str__(self):
        return self.name 

class AppealForm(models.Model):
    form_name = models.CharField(max_length=100)

    def __str__(self):
        return self.report_form_name

class Appeal(models.Model):
    organization = models.ForeignKey(Organization, on_delete=models.SET_NULL, blank=True, null=True)
    appeal_form = models.ForeignKey(AppealForm, on_delete=models.CASCADE, blank=True, null=True)
    appeal_number = models.CharField(max_length=100, blank=True, null=True)
    applicant_first_name = models.CharField(max_length=100, blank=True, null=True)
    applicant_second_name = models.CharField(max_length=100, blank=True, null=True)
    date = models.DateField(blank=True, null=True)
    appeal_body = models.TextField()

用于创建精选折线图的Chart JS脚本:

new Chart(chartTwo, {
         type: 'line',
         data: {
            labels: ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'],
            datasets: [
                  {
                  label: 'written',
                  data: [
                     Math.floor(Math.random() * 100),
                     Math.floor(Math.random() * 100),
                     Math.floor(Math.random() * 100),
                     Math.floor(Math.random() * 100),
                     Math.floor(Math.random() * 100),
                     Math.floor(Math.random() * 100),
                  ],
                  borderColor: "green",
                  backgroundColor: "green",
                  },
                  {
                  label: 'oral',
                  data: [
                     Math.floor(Math.random() * 100),
                     Math.floor(Math.random() * 100),
                     Math.floor(Math.random() * 100),
                     Math.floor(Math.random() * 100),
                     Math.floor(Math.random() * 100),
                     Math.floor(Math.random() * 100),
                  ],
                  borderColor: "blue",
                  backgroundColor: "blue",
                  },
            ]
         },
         options: {
            responsive: true,
            scales: {
            y: {
                  min: -20,
                  max: 120,
            }
            }
         },
      })

Qestion:,how the query will look like for this graph using AppealForm model?.

附注:我想要从年初到年底逐月统计每个外观表单模型对象的数量.今年还没有结束,所以在这个月剩下的时间里,我希望获得0值以响应地粘贴到图表中.

=

更新:

组织模型的对象:

# name
1 Apple
2 Samsung

外观模型的对象:

# form_name
1 written
2 oral

上诉对象模式:

there are more appeals to show here, but it does not play a role in the query I want

更新问题:如何查询OualForm(specalForm.objects.et...)表以获取上述折线图的数据?

推荐答案

如果我理解正确的话,您想要计算本年度每个月的上诉类型的对象,以及与appeal_formappeal_form__form_name="oral"分开的对象吗?

我所知道的是有效的,按月计算.我已经用我自己的名为PO(采购订单)的模型测试了这一点,它的字段日期就像您的上诉一样.

>>> qs1 = PO.objects.filter( date__year=2023)
>>> result = qs1.aggregate( **{ 
        f'{x+1:02}' : Count('date', filter=Q(date__month=x+1) )
        for x in range(12) })
>>> result
{'01': 6, '02': 3, '03': 3, '04': 3, '05': 1, '06': 0, '07': 0, '08': 0, '09': 0, '10': 0, '11': 0, '12': 0}

>>> [ x[1] for x in sorted( result.items())]
[6, 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0]

简单的result.values()给出相同的列表,但这在查询集结果的排序方面需要很大的信任.最好是根据需要显式地对它们进行排序.

此外,这是一个打字错误,没有放f'M{x+1:02}',所以键以字母字符开头.但是,它成功了!谁知道Python允许这样做呢?

现在,使用您的一个查询可以运行两个类似的查询:

qs1 = Appeal.objects.filter( date__year=2023, appeal_form__form_name='oral')  
oral_results = qs1.aggregate( **{ ... 
qs2 = Appeal.objects.filter( date__year=2023, appeal_form__form_name='written')  
written_results = qs2.aggregate( **{ ... 

或者,您可以将条件放入Q对象(共24个)中,然后使用一个查询完成所有操作,然后将它们分离开来.代码将不会那么清晰,也不会更长.

我不是数据库专家,我不知道这是否有效.就我的目的而言,我没有处理足够的数据库行,以至于PostgreSQL甚至都不会 blink ,而且这些报告每月都会完成一次!

顺便说一句,用这种技术可以很容易地持续12个月

>>> from datetime import date

>>> qs3 = PO.objects.filter( date__range=(date(2022,6,1), date(2023,5,31)) )   
>>> months = [(2022,x) for x in range(6,13)] + [ (2023,x) for x in range(1,6)]
>>> months
[(2022, 6), (2022, 7), (2022, 8), (2022, 9), (2022, 10), (2022, 11), (2022, 12), (2023, 1), (2023, 2), (2023, 3), (2023, 4), (2023, 5)]

 >>> qs3.aggregate( **{ f'{x[0]}_{x[1]:02}' : Count('date', filter=Q(date__month=x[1]) ) for x in months })
{'2022_06': 2, '2022_07': 5, '2022_08': 0, '2022_09': 6, '2022_10': 4, '2022_11': 1, '2022_12': 3, '2023_01': 6, '2023_02': 3, '2023_03': 3, '2023_04': 3, '2023_05': 1} 

Django相关问答推荐

如何根据属性的 Select 对查询集进行排序

我的Django终结点不访问HAS_OBJECT_PERMISSION方法

如何从列中捕获数据并将其添加到下拉菜单中,以便表单填充另一个表

执行官/start.sh:没有这样的文件或目录

使用自定义的AuthBackend时,无法使用request.user.is_authenticated或@login_required修饰符

Django JSONField 过滤

Django 基于角色的视图?

在 Django 过滤器语句中,__exact 和等号 (=) 有什么区别?

NoReverseMatch 错误

Django:如何使用动态(非模型)数据预填充 FormView?

OrderingFilter 没有属性filter_queryset

如何在 django 元素中开始做 TDD?

Django 应用程序中的版本号

django 模板列表变量中的最后一个元素

Django:以 10 为底的 int() 的无效文字

过滤 Django 数据库中包含数组中任何值的字段

想要在 Django 测试中禁用信号

如何获取 Django 模型字段对象的值

如何从 django 请求中获取完整的 url

通过 django 分页仅显示部分页码