In my DRF app I have the following model, serializer and view.
models.py
class Log(models.Model):
plant = models.ForeignKey(Plant, on_delete=models.CASCADE)
date_time = models.DateTimeField()
water_consumption = models.PositiveSmallIntegerField()
elec_consumption = models.PositiveSmallIntegerField()
serializers.py
class ConsumptionSerializer(serializers.ModelSerializer):
class Meta:
model = Log
fields = ("water_consumption", "elec_consumption")
views.py
class ConsumptionViewSet(viewsets.ModelViewSet):
permission_classes = [permissions.IsAuthenticated, ]
serializer_class = ConsumptionSerializer
def get_queryset(self):
# Get params from url
start_date = self.request.query_params.get('start_date')
end_date = self.request.query_params.get('end_date')
# Make sure params are not null
if start_date is not None and end_date is not None:
queryset = queryset.filter(date_time__range=[start_date, end_date])
return queryset
else:
raise ValidationError({"ERROR": ["No params found in url"]})
This works and it outputs something like this in JSON:
[
{
"water_consumption": 1,
"electrical_consumption": 1
},
{
"water_consumption": 1,
"electrical_consumption": 1
},
{
"water_consumption": 1,
"electrical_consumption": 1
},
]
What I would like to achieve is to receive some aggregated data alongside those data, like this:
{
"total_water_consumption": 3,
"total_elec_consumption": 3,
"detailed_logs": [{
"water_consumption": 1,
"electrical_consumption": 1
},
{
"water_consumption": 1,
"electrical_consumption": 1
},
{
"water_consumption": 1,
"electrical_consumption": 1
}]
}
How should I customise the queryset to have the total values added?
Thank you in advance.
CodePudding user response:
You can do it with SerializerMethodField
in your serializer file
Docs in : https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield
And you can access request
in serializer as context
:
from django.db.models import Sum
class ConsumptionSerializer(serializers.ModelSerializer):
total_water_consumption = serializers.SerializerMethodField()
total_elec_consumption = serializers.SerializerMethodField()
class Meta:
model = Log
fields = ("water_consumption", "elec_consumption")
def get_total_water_consumption(self, obj):
request = self.context['request']
query_params = request.query_params.get(...)
return Log.objects.filter(...).aggregate(Sum('water_consumption')).get('water_consumption__sum')
def get_total_elec_consumption(self, obj):
request = self.context['request']
query_params = request.query_params.get(...)
return Log.objects.filter(...).aggregate(Sum('elec_consumption')).get('elec_consumption__sum')