Python Django按天、周、月、年筛选时间戳数据组

Python Django按天、周、月、年筛选时间戳数据组,python,django,django-rest-framework,django-orm,django-filters,Python,Django,Django Rest Framework,Django Orm,Django Filters,我有一个djangoDRF应用程序,我在其中存储基于API响应的定期timeseries数据。这是我的 model.py # Model to store the Alexa API Data class Alexa(models.Model): created_at = models.DateTimeField(auto_now_add=True) extra = jsonfield.JSONField(null=True) rank = models.Positiv

我有一个djangoDRF应用程序,我在其中存储基于API响应的定期timeseries数据。这是我的 model.py

# Model to store the Alexa API Data
class Alexa(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    extra = jsonfield.JSONField(null=True)
    rank =  models.PositiveIntegerField(default=0, null=True)
我正在使用django过滤器根据范围查询数据。 Like/api/alexa/?created_at_uuulte=2020-02-14T09:15:52.329641Z返回2020-02-14T09:15:52.329641Z之前创建的所有数据

是否有一种方法可以构建一个端点来返回基于我传递的查询参数按天、周、月和年分组的聚合数据。例如 /api/alexa/?创建时间:2020-02-14T09:15:52.329641Z&group\u by=month将返回

[
    {
        "created_at": "2020-01-01T00:00:00.000000Z",
        "extra": "{'load_time': 00, 'backlink': 0}", <- Aggregated Data 
        "rank": 0                                    <- Aggregated Data
    },
    {
        "created_at": "2020-02-01T00:00:00.000000Z",
        "extra": "{'load_time': 00, 'backlink': 0}", <- Aggregated Data 
        "rank": 0                                    <- Aggregated Data 
    },
 ]
我看到过几个代码片段在进行聚合,但没有一个完全满足我的要求,也没有一个完全了解这个主题

我是Django和building analytics Dashboard的新手,如果有任何其他方法可以在前端图形中表示此类消费时间序列数据,我也将非常感谢您的建议

编辑: 这是我的serializer.py

class AlexaSerializer(serializers.ModelSerializer):
     class Meta:
         model = Alexa
         fields = '__all__'
首先,类AlexaViewSet不是序列化程序,而是ViewSet。您没有指定该视图集上的序列化程序类,因此需要指定该类

另一方面,如果要在URL上传递自定义查询参数,则应重写此ViewSet的list方法,并解析在请求对象中传递的查询字符串,以检索group_by的值,验证它,然后自行执行聚合

另一个问题是,您还需要定义什么是聚合JSON字段,这是SQL中不支持的,它是非常相关的,因此您可能需要考虑重新设计如何存储JSON字段的信息,如果您想在其内部的字段上执行聚合。我建议在将字段存储在数据库中时从JSON中提取要聚合的字段,并将它们分别放在SQL列中,以便以后可以执行聚合。 客户端还可以将aggregation操作作为查询参数传递,例如aggregation=sum或aggregation=avg

在一个简单的情况下,如果您只需要排名的平均值,这应该是一个有用的示例,您可以添加TruncQuarter等:

类AlexaViewSetviewsets.ModelViewSet: 序列化程序\u类=序列化程序 queryset=Alexa.objects.all 筛选器_字段={'created_at':['iexact','lte','gte']} http_method_names=['get','post','head'] GROUP_CASTING_MAP={用于分组时输出重置日期时间 “day”:CastTruncDate“创建时间”,输出字段=日期时间字段, “月”:CastTruncMonth“已创建”,输出字段=日期时间字段, “周”:CastTruncWeek“已创建”,输出字段=日期时间字段, “年”:CastTruncYear“已创建”,输出字段=日期时间字段, } GROUP_ANNOTATIONS_MAP={定义用于分组的字段 “日”:{ “天”:TruncDay“创建于”, 'month':TruncMonth'created_at', “年”:TruncYear“创建于”, }, “星期”:{ “周”:TruncWeek“创建于” }, “月”:{ 'month':TruncMonth'created_at', “年”:TruncYear“创建于”, }, “年”:{ “年”:TruncYear“创建于”, }, } def listself,请求,*args,**kwargs: 分组依据字段=请求。获取。获取“分组依据”,无 如果“分组依据”字段和“分组依据”字段不在self.group\u CASTING\u MAP.keys中:验证可能的值 return Responsestatus=status.HTTP\u 400\u错误\u请求 queryset=self.filter\u querysetself.get\u queryset 如果按字段分组: queryset=queryset.annotate**self.GROUP\u ANNOTATIONS\u映射[按字段分组]\ .values*self.GROUP\u注释\u映射[按字段分组]\ .annotaterank=Avg'rank',创建时=self.GROUP\u铸造地图[按字段分组]\ .值“排名”、“创建位置” page=self.paginate\u querysetqueryset 如果页面不是“无”: serializer=self.get\u serializerpage,many=True 返回self.get_paginated_responseserializer.data serializer=self.get\u serializerqueryset,many=True 返回响应Serializer.data 对于这些值:

得到/alexa [ { id:1, 创建时间:2020-03-16T12:04:59.096098Z, 额外:{}, 排名:2 }, { id:2, 创建时间:2020-02-15T12:05:01.907920Z, 额外:{}, 排名:64 }, { id:3, 创建时间:2020-02-15T12:05:03.890150Z, 额外:{}, 排名:232 }, { id:4, 创建时间:2020-02-15T12:05:06.357748Z, 额外:{}, 排名:12 } ] 获取/alexa/?按天分组 [ { 创建时间:2020-02-15T00:00:00Z, 额外:空, 排名:102 }, { 创建时间:2020-03-16T00:00:00Z, 额外:空, 排名:2 } ] 获取/alexa/?分组时间=周 [ { 创建时间:2020-02-10T00:00:00Z, 额外:空, 排名:102 }, { 创建时间:2020-03-16T00:00:00Z, 额外:空, 排名:2 } ] GET/alexa/?group\u by=月 [ { 创建时间:2020-02-01T00:00:00Z, 额外:空, 排名:102 }, { 创建时间:2020-03-01T00:00:00Z, 额外:空, 排名:2 } ] GET/alexa/?group\u by=年 [ { 创建时间:2020-01-01T00:00:00Z, 额外:空, 排名:77 } ]
谢谢你这么快的回复,我理解你的方法!你能帮我理解这个错误的原因吗?我在尝试上面的代码时得到了这个。我已经添加了我的序列化程序,以防它与AttributeError相关/api/alexa/“dict”对象没有属性“extra”,我很高兴您能理解它。你能告诉我更多关于你的错误的细节吗?也许整个stacktrace都会有帮助。据我所知,错误似乎是我的序列化程序在dict中需要一个“额外”属性。当我使用exclude=['extra']将它从序列化程序中排除时,一切似乎都按预期工作。这是全文
class AlexaViewSet(viewsets.ModelViewSet):
    queryset = Alexa.objects.all()
    filter_fields = {'created_at' : ['iexact', 'lte', 'gte']}
    http_method_names = ['get', 'post', 'head']
class AlexaSerializer(serializers.ModelSerializer):
     class Meta:
         model = Alexa
         fields = '__all__'