Django Szűrés timestamp adatok GROUP BY nap, hét, hónap, év

szavazat
30

Van egy Django (DRF) app, amelyben én tárolására periodikus előre definiált adatok alapján API választ. Itt van a 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)

Én a Django-szűrők lekérdezési adatok alapján egy sor (__lte, __gte). Mint /api/alexa/?created_at__lte=2020-02-14T09:15:52.329641Zvissza az összes adat előtt létrehozott2020-02-14T09:15:52.329641Z

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

Van egy módja annak, hogy építsenek egy végpont visszatérni összesített adatok szerint csoportosított nap, hét, hónap, év alapján lekérdezési paraméterek átadom. Például /api/alexa/?created_at__lte=2020-02-14T09:15:52.329641Z&group_by=monthvisszatér

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

Itt a jelenlegi serializer.py

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

Láttam több töredék csinál összesítés, de egyik sem teljesen kielégítő a követelményeknek sem ad nekem egy teljes képet a témáról.

Én vagyok az új Django és épület analitika műszerfalak általában, ha van más módja a képviselő ilyen előre definiált adatok fogyasztásra front-end grafikonok, örömmel vennénk a javaslatokat, hogy hogy is.

A kérdést 15/02/2020 08:48
felhasználó
Más nyelveken...                            


1 válasz

szavazat
0

Először is, az osztály AlexaViewSetnem egy-soros, hanem egy ViewSet. Nem adta meg a Comment osztály hogy ViewSet úgyhogy meg kell határoznia, hogy a.

A másik oldalon, ha azt szeretné, hogy adja át az egyéni lekérdezési paramétert az URL, akkor felülírják listmódszer ennek ViewSet és feldolgozni a query string telt el a requesttárgy letölteni az értékét group_by, érvényesíti azt, majd PERFOM az összesítés youself .

A másik probléma, hogy látom, hogy akkor is meg kell határozni, mi az, hogy összességében a JSON mező, amely nem támogatja az SQL és ez nagyon relatív, ezért azt szeretné, hogy újratervezés, hogyan tárolja az információk JSON mezőt, ha azt szeretné, hogy PERFOM csoportosulásai mezőkön belül. Azt javasoljuk, kitermelése a kívánt mezőket összesíteni a JSON (amikor tárolja azokat az adatbázisban), és tedd őket egy SQL oszlop külön, így lehet elvégezni csoportosulásai később. Az ügyfél is átmennek a Agrégation műveletet mint egy lekérdezési paramétert, például a aggregation=sumvagy a aggregation=avg.

Egy egyszerű esetben, amikor csak kell az átlagos soraiban ez hasznos példaként (te is add TruncQuarter, stb):

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)

Mert ezek az értékek:

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
    }
]
Válaszolt 15/02/2020 20:34
a forrás felhasználó

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