Как сгруппировать набор запросов по определенному полю в 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 непосредственно.