Django Filtre damgası veri GRUBU TARAFINDAN gün, hafta, ay, yıl

oy
30

I API yanıtına göre periyodik timeseries verileri depolamak olan bir django (DRF) uygulaması vardır. İşte benim model.py olduğunu

# 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)

Bir aralık (__lte, __gte) dayalı sorgu verilerine django-filtreleri kullanıyorum. Gibi /api/alexa/?created_at__lte=2020-02-14T09:15:52.329641Zönce oluşturulan tüm verileri döndürür2020-02-14T09:15:52.329641Z

[
    {
        id: 1,
        created_at: 2020-02-03T19:30:57.868588Z,
        extra: {'load_time': 00, 'backlink': 0},
        rank: 0
    },
    ...
 ]

Ben geçmesi Sorgu parametreleri temelinde gün, hafta, ay ve yıla göre gruplandırılmış toplanan verileri döndürmek için bir bitiş noktası oluşturmak için bir yolu var mı. Örneğin, /api/alexa/?created_at__lte=2020-02-14T09:15:52.329641Z&group_by=monthdönecekti

[
    {
        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 
    },
 ]

İşte benim şimdiki serializer.py var

class AlexaViewSet(viewsets.ModelViewSet):
    queryset = Alexa.objects.all()
    filter_fields = {'created_at' : ['iexact', 'lte', 'gte']}
    http_method_names = ['get', 'post', 'head']

Ben toplanmasına yapıyor birkaç parçacıkları gördük ama hiçbiri tamamen benim gereklerini yerine getiren, ne de bana konu hakkında tam bir fikir veriyor.

Ben ön uç grafiklerinde tüketim için böyle timeseries verilerini temsil etme başka bir yolu varsa, bu işe önerilerinizi takdir de ediyorum, genel olarak Django yeni ve bina analitik gösterge tabloları duyuyorum.

Oluştur 15/02/2020 saat 08:48
kullanıcı
Diğer dillerde...                            


1 cevaplar

oy
0

Her şeyden önce, sınıf AlexaViewSetbir serileştirici ama ViewSet değil. Ben bunu belirtmek gerekir böylece o ViewSet üzerinde serileştirici sınıfını belirtmedi.

Eğer URL'de özel sorgu parametresi geçirmek istiyorsanız Öte yandan, o zaman geçersiz kılmak gerekir listbu ViewSet metodunu ve geçirilen sorgu dizesi ayrıştırmak requestdeğerini almak için nesne group_by, bu doğrulamak ve sonra agregasyonu da kendin perfom .

Görüyorum başka sorun da SQL desteklenmeyen bir JSON alanını bir araya getirmek için ne olduğunu tanımlamak gerekir olmasıdır ve eğer isterseniz bu JSON alanın bilgi depolamak nasıl yeniden tasarlama düşünebilirsiniz yüzden, çok göreceli İçinde alanlarda perfom toplulaştırmalara. Sana (veritabanında saklayarak olduğunda) JSON'dan bir araya getiren ve daha sonra toplamaları gerçekleştirmek böylece ayrı bir SQL sütununda koymak istediğiniz alanları ayıklanması öneririm. İstemci aynı zamanda, örneğin, bir sorgu parametresi olarak agregasyon işlemi geçebileceği aggregation=sumveya aggregation=avg.

Sadece bu örnek (siz ekleyebilirsiniz olarak yararlı olmalıdır rütbeleri ortalama gereken basit durumda, TruncQuartervs.):

class AlexaViewSet(viewsets.ModelViewSet):
    serializer_class = AlexaSerializer
    queryset = Alexa.objects.all()
    filter_fields = {'created_at': ['iexact', 'lte', 'gte']}
    http_method_names = ['get', 'post', 'head']

    GROUP_CASTING_MAP = {  # Used for outputing the reset datetime when grouping
        'day': Cast(TruncDate('created_at'), output_field=DateTimeField()),
        'month': Cast(TruncMonth('created_at'), output_field=DateTimeField()),
        'week': Cast(TruncWeek('created_at'), output_field=DateTimeField()),
        'year': Cast(TruncYear('created_at'), output_field=DateTimeField()),
    }

    GROUP_ANNOTATIONS_MAP = {  # Defines the fields used for grouping
        'day': {
            'day': TruncDay('created_at'),
            'month': TruncMonth('created_at'),
            'year': TruncYear('created_at'),
        },
        'week': {
            'week': TruncWeek('created_at')
        },
        'month': {
            'month': TruncMonth('created_at'),
            'year': TruncYear('created_at'),
        },
        'year': {
            'year': TruncYear('created_at'),
        },
    }

    def list(self, request, *args, **kwargs):
        group_by_field = request.GET.get('group_by', None)
        if group_by_field and group_by_field not in self.GROUP_CASTING_MAP.keys():  # validate possible values
            return Response(status=status.HTTP_400_BAD_REQUEST)

        queryset = self.filter_queryset(self.get_queryset())

        if group_by_field:
            queryset = queryset.annotate(**self.GROUP_ANNOTATIONS_MAP[group_by_field]) \
                .values(*self.GROUP_ANNOTATIONS_MAP[group_by_field]) \
                .annotate(rank=Avg('rank'), created_at=self.GROUP_CASTING_MAP[group_by_field]) \
                .values('rank', 'created_at')

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

Bu değerler için:

GET /alexa
[
    {
        "id": 1,
        "created_at": "2020-03-16T12:04:59.096098Z",
        "extra": "{}",
        "rank": 2
    },
    {
        "id": 2,
        "created_at": "2020-02-15T12:05:01.907920Z",
        "extra": "{}",
        "rank": 64
    },
    {
        "id": 3,
        "created_at": "2020-02-15T12:05:03.890150Z",
        "extra": "{}",
        "rank": 232
    },
    {
        "id": 4,
        "created_at": "2020-02-15T12:05:06.357748Z",
        "extra": "{}",
        "rank": 12
    }
]
GET /alexa/?group_by=day
[
    {
        "created_at": "2020-02-15T00:00:00Z",
        "extra": null,
        "rank": 102
    },
    {
        "created_at": "2020-03-16T00:00:00Z",
        "extra": null,
        "rank": 2
    }
]
GET /alexa/?group_by=week
[
    {
        "created_at": "2020-02-10T00:00:00Z",
        "extra": null,
        "rank": 102
    },
    {
        "created_at": "2020-03-16T00:00:00Z",
        "extra": null,
        "rank": 2
    }
]

GET /alexa/?group_by=month
[
    {
        "created_at": "2020-02-01T00:00:00Z",
        "extra": null,
        "rank": 102
    },
    {
        "created_at": "2020-03-01T00:00:00Z",
        "extra": null,
        "rank": 2
    }
]
GET /alexa/?group_by=year
[
    {
        "created_at": "2020-01-01T00:00:00Z",
        "extra": null,
        "rank": 77
    }
]
Cevap 15/02/2020 saat 20:34
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more