如何在 Django Rest Framework ModelViewSets 中添加聚合值
How to add aggregate values in Django Rest Framework ModelViewSets
在我的 DRF 应用程序中,我有以下模型、序列化程序和视图。
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"]})
这有效,它在 JSON 中输出类似这样的内容:
[
{
"water_consumption": 1,
"electrical_consumption": 1
},
{
"water_consumption": 1,
"electrical_consumption": 1
},
{
"water_consumption": 1,
"electrical_consumption": 1
},
]
我想要实现的是在接收这些数据的同时接收一些聚合数据,如下所示:
{
"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
}]
}
我应该如何自定义查询集以添加总值?
提前致谢。
您可以在序列化程序文件中使用 SerializerMethodField
文档位于:https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield
并且您可以在序列化程序中访问 request
作为 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')
在我的 DRF 应用程序中,我有以下模型、序列化程序和视图。
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"]})
这有效,它在 JSON 中输出类似这样的内容:
[
{
"water_consumption": 1,
"electrical_consumption": 1
},
{
"water_consumption": 1,
"electrical_consumption": 1
},
{
"water_consumption": 1,
"electrical_consumption": 1
},
]
我想要实现的是在接收这些数据的同时接收一些聚合数据,如下所示:
{
"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
}]
}
我应该如何自定义查询集以添加总值?
提前致谢。
您可以在序列化程序文件中使用 SerializerMethodField
文档位于:https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield
并且您可以在序列化程序中访问 request
作为 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')