I have a qs qs_payments
that returns the following:
[
{
"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
}
]
I now try to re-group the data so that each month contains all items of that particular month (in the given example there would be two nested items for May/2021-05-21)
I tried the following using itertools but this returns Payment object is not subscriptable
. Context is that I want to render one component with its line items in React.js.
class PayrollRun(APIView):
...
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)
The desired outcome is s.th. like (if that makes sense?)
[
{
"2021-05-01": [{
"id": 69,
"amount": 4305,
"offer": 39
},
{
"id": 19,
"amount": 3745,
"offer": 38
}],
},
"2021-04-01": [{
...
}],
]
Update to try to even simpler approach with a related field to Period
# models.py
class Period(models.Model):
period = models.DateField()
class Payment(models.Model):
offer = models.ForeignKey(Offer, on_delete=models.CASCADE)
month = models.ForeignKey(Period, on_delete=models.CASCADE)
amount = models.PositiveIntegerField()
# serializers.py
class PaymentSerializer(serializers.ModelSerializer):
class Meta:
model = Payment
fields = '__all__'
class PeriodSerializer(serializers.ModelSerializer):
payments = serializers.SerializerMethodField()
class Meta:
model = Period
fields = '__all__'
# views.py
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)
print(qs_payments)
serializer = PeriodSerializer(qs_payments, many=True)
return Response(serializer.data)
CodePudding user response:
What about something like this?
models.py
class Month(...):
date = models.DateField(...)
Then in your serializers:
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
EDIT:
You can simplify this further by adding a foreign key relation to a Month
on your Payment
model, then you don't need to write the get_payments
method, you can just serialize the Payments
on each Month
directly.