Как сгруппировать набор запросов по определенному полю в Django?

У меня есть qs qs_payments, который возвращает следующее:

[
    {
        "id": 19,
        "month": "2021-05-01",
        "amount": 3745,
        "offer": 38
    },
    {
        "id": 67,
        "month": "2021-03-01",
        "amount": 4235,
        "offer": 39
    },
    {
        "id": 68,
        "month": "2021-04-01",
        "amount": 4270,
        "offer": 39
    },
    {
        "id": 69,
        "month": "2021-05-01",
        "amount": 4305,
        "offer": 39
    }
]

Теперь я пытаюсь перегруппировать данные так, чтобы каждый месяц содержал все элементы этого конкретного месяца (в приведенном примере было бы два вложенных элемента для мая/2021-05-21)

Я попробовал следующее, используя itertools, но это возвращает Payment object is not subscriptable. Дело в том, что я хочу вывести один компонент с его элементами в React.js.

class PayrollRun(APIView):
    def get(self, request):
        # Loop payment table for company related payments, create dict of dict for each month
        # Get todays date
        today = datetime.date(datetime.now())

        # Get the related company according to the logged in user
        company = Company.objects.get(userprofile__user=request.user)

        # Get a queryset of payments that relate to the company and are not older than XX days
        qs_payments = Payment.objects.filter(offer__company=company).filter(
            month__gte=today - timedelta(days=600),
            month__lte=today
        )
        payment_runs = [{'subject': k, 'Results': list(g)} for k, g in itertools.groupby(qs_payments, key=itemgetter('month'))]

        print(payment_runs)

        serializer = PaymentSerializer(qs_payments, many=True)
        return Response(serializer.data)

Желаемый результат - это s.th. like (если это имеет смысл?)

[
    {
     "2021-05-01" [{
        "id": 69,
        "amount": 4305,
        "offer": 39
     },
     {
        "id": 19,
        "amount": 3745,
        "offer": 38
     }],
    },
    "2021-04-01" [{
       ...
    }],
]

А как насчет чего-то подобного?

models.py

class Month(...):
   date = models.DateField(...)

Затем в ваших сериализаторах:

serializers.py

class PaymentSerializer(...):
    ...

class MonthSerializer(...):

    payments = serializers.SerializerMethodField()

    def get_payments(self, obj):
        payments = Payment.objects.filter(
            month = obj.date
        )
        return PaymentSerializer(payments, many=True).data

    class Meta:
        fields = ['payments', ...]
        model = Month

РЕДАКТИРОВАНИЕ:

Вы можете упростить это еще больше, добавив отношение внешнего ключа к Month на вашей Payment модели, тогда вам не нужно писать метод get_payments, вы можете просто сериализовать Payments на каждом Month непосредственно.

Вернуться на верх