如何从查询集中选择数据并按特定日期的计数分组

时间:2019-05-23 10:08:29

标签: python django django-queryset django-aggregation

当我查询数据库时,我得到三个相同计数的相同条目三次。在结果列表中,我只想获得一个显示这些计数总和的条目。

我要显示的是特定时期的总数。

在查询中,我输入日期(从-到),metric_type,data_type和发布年份。

例如,当我输入时我在网站上

from 201903 until 201905 

我检索了此期间已被访问的三个标题以及它们被访问了多少次。

Title, Publisher,    DOI,   data_type,YOP,[some other stuff] Counts

Title A  publisherA   1234    Article, 2006, [some_other_stuff], 3
Title A  publisherA   1234    Article, 2006, [some_other_stuff], 5
Title A  publisherA   1234    Article, 2006, [some_other_stuff], 3

我需要的是类似的东西

Title, publisher, DOI,   data_type, YOP,  [some_other_stuff],  Total period

Title A, publisherA 1234   Article, 2006,   [some_other_stuff],    11


在views.py中,我有以下代码:

    q_report = Q()


        var0 = self.request.GET.get("period1", "")
        var1 = self.request.GET.get("period2", "")
        var2 = self.request.GET.get("metric_type", "")
        var3 = self.request.GET.get("data_type", "")
        var4 = self.request.GET.get("YOP", "")



        if var0:
            q_report = q_report & (Q(month__gte=var0) & Q(month__lte=var1) )
            #q_report_count = q_report_count & (Count(month__gte=var0) & Count(month__lte=var1) )
        if var2:
            q_report = q_report & (Q(metric_type=var2))
            #q_report_count = q_report_count & (Q(metric_type=var2))
        if var3:
             q_report = q_report & (Q(data_type=var3))
        if var4:
             q_report = q_report & (Q(YOP=var4))

如果我使用

qs = self.model.objects.filter(q_report).select_related()

我将取回三个条目

结果是

<QuerySet [<Model: Title A>, <Model: Title A>, <Model: Title A>]>

我可以轻松地通过使用

来计算总数
total = self.model.objects.aggregate(total=Sum('counts', filter=q_report))

结果是

{total : 11.0}

但理想情况下,我还需要获取其他值

现在,我看不到如何将两者融合在一起,即类似


<QuerySet [<Model: {'title':Title A, 'total':11}>, Model: {'title':Title B, 'total':7}>]

我什至不知道这是可能的还是想要的。但是我需要返回查询集和总数。

有人可以帮忙吗?谢谢。

2 个答案:

答案 0 :(得分:1)

从本质上讲,这是一个建模问题。而不是像这样定义模型:

# modeling with data duplication

class SomeModel(models.Model):
    title = models.CharField(max_length=256)
    publisher = models.CharField(max_length=256)
    doi = models.CharField(max_length=256)
    publication_type = models.CharField(max_length=128)
    year = models.IntegerField()
    date = models.DateField()
    counts = models.IntegerField()

您应该制作一个像Publication这样的模型,并将SomeModel链接到那个Publication,例如:

# modeling without data duplication

class Publication(models.Model):
    title = models.CharField(max_length=256)
    publisher = models.CharField(max_length=256)
    doi = models.CharField(max_length=256)
    publication_type = models.CharField(max_length=128)
    year = models.IntegerField()

class PublicationSale(models.Model):
    publication = models.ForeignKey(Publication, on_delete=models.CASCADE)
    date = models.DateField()
    counts = models.IntegerField()

这将减小数据库的大小,减少数据库出现不一致的可能性(例如,如果您更改发布年份,即某些记录未正确更新),并且可能使某些查询的数据库速度更快。

在这种情况下,您可以查询:

from django.db.models import Sum

Publication.objects.annotate(
    total=Sum('publication_sale__counts')
)

然后,您检索带有QuerySet个对象的Publication对象,这些对象带有一个额外的属性.totals,该属性是与相关的counts的总和PublicationSale个对象。

如果不执行此重塑,则可以使用:

from django.db.models import Sum

qs = self.model.objects.filter(q_report).values(
    'title', 'publisher', 'doi', 'publication_type', 'year'
).annotate(
    total=Sum('counts')
).order_by(
    'title', 'publisher', 'doi', 'publication_type', 'year'
)

然后将产生QuerySet个字典:

<QuerySet [
    {'title': 'Title A', 'publisher': 'pubA', ..., 'total': 11},
    {'title': 'Title B', 'publisher': 'pubA', ..., 'total': 7},
    {'title': 'Title A', 'publisher': 'pubB', ..., 'total': 3},
]>

但是您可以看到查询不会产生模型,并且在每次添加“功能相关实体”的额外数据时都需要更新查询。 / p>

答案 1 :(得分:0)

通过

替换查询
self.model.objects.filter(q_report).annotate(total=Sum('counts')).values('title','total')

总计将是您要求和的字段