DRF:聚合相似的条目名称
DRF: Aggregate similar entries name
我想按名称合并条目并对它们的其他字段执行添加。
在本例中,我想获取具有相同项目名称的条目的 total_cost 和 average_pct。
假设:
# models.py
class Project(models.Model):
project = models.CharField(max_length=200)
subproject = models.CharField(max_length=200)
physical_pct = models.FloatField()
cost = models.FloatField()
# serializers.py
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = '__all__'
# views.py
class ProjectsViewSet(viewsets.ModelViewSet):
serializer_class = ProjectSerializer
def get_queryset(self):
queryset = Project.objects.all()
return queryset
如果我有 3 个条目:
[
{
"project": "Project-X",
"subproject": "Subproject-1",
"physical_pct": 58,
"cost": 1000.00
},
{
"project": "Project-X",
"subproject": "Subproject-2",
"physical_pct": 100,
"cost": 2000.00
},
{
"project": "Project-Y",
"subproject": "Subproject-1",
"physical_pct": 73,
"cost": 560.00
}
]
我想要的输出:
[
{
"project": "Project-X",
"average_pct": 79,
"total_cost": 3000.00
},
{
"project": "Project-Y",
"average_pct": 73,
"total_cost": 560.00
}
]
更新 1:
在values()的前提下,必须根据字段参数对相似条目进行分组。然而,当我尝试时,:
# serializers.py
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = ['id', 'project', 'cost']
# views.py
from django.db.models import Avg, Sum
class ProjectsViewSet(viewsets.ModelViewSet):
serializer_class = ProjectSerializer
def get_queryset(self):
queryset = Project.objects.values('project').\
annotate(total_cost=Sum('cost'))
return queryset
我得到一个错误:
"Got KeyError when attempting to get a value for field `cost` on serializer `ProjectSerializer`.\nThe serializer field might be named incorrectly and not match any attribute or key on the `dict` instance.\nOriginal exception text was: 'cost'."
您可以在注释前使用 .values()
按项目分组。
from django.db.models import Avg, Sum
Project.objects.values('project').annotate(
total_cost=Sum('cost'),
average_pct=Avg('physical_pct'),
)
关于您的更新,由于分组,成本字段不存在于查询集中。 .values()
和 .annotate()
之外的字段中的 None 将出现。要在序列化程序中使用总成本,您需要使用 SerializerMethodField()
.
class ProjectSerializer(serializers.ModelSerializer):
total_cost = serializers.SerializerMethodField()
class Meta:
model = Project
fields = ['project', 'total_cost']
def get_total_cost(self, instance):
return instance.total_cost
如果您想用总成本而不是分组来注释每个实例,并且您使用的是 Django >= 2.0,那么您可以执行以下操作。
from django.db.models import F, Q, Sum
Project.objects.annotate(total_cost=Sum('cost', filter=Q(project=F('project'))))
我想按名称合并条目并对它们的其他字段执行添加。
在本例中,我想获取具有相同项目名称的条目的 total_cost 和 average_pct。
假设:
# models.py
class Project(models.Model):
project = models.CharField(max_length=200)
subproject = models.CharField(max_length=200)
physical_pct = models.FloatField()
cost = models.FloatField()
# serializers.py
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = '__all__'
# views.py
class ProjectsViewSet(viewsets.ModelViewSet):
serializer_class = ProjectSerializer
def get_queryset(self):
queryset = Project.objects.all()
return queryset
如果我有 3 个条目:
[
{
"project": "Project-X",
"subproject": "Subproject-1",
"physical_pct": 58,
"cost": 1000.00
},
{
"project": "Project-X",
"subproject": "Subproject-2",
"physical_pct": 100,
"cost": 2000.00
},
{
"project": "Project-Y",
"subproject": "Subproject-1",
"physical_pct": 73,
"cost": 560.00
}
]
我想要的输出:
[
{
"project": "Project-X",
"average_pct": 79,
"total_cost": 3000.00
},
{
"project": "Project-Y",
"average_pct": 73,
"total_cost": 560.00
}
]
更新 1:
在values()的前提下,必须根据字段参数对相似条目进行分组。然而,当我尝试时,:
# serializers.py
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = ['id', 'project', 'cost']
# views.py
from django.db.models import Avg, Sum
class ProjectsViewSet(viewsets.ModelViewSet):
serializer_class = ProjectSerializer
def get_queryset(self):
queryset = Project.objects.values('project').\
annotate(total_cost=Sum('cost'))
return queryset
我得到一个错误:
"Got KeyError when attempting to get a value for field `cost` on serializer `ProjectSerializer`.\nThe serializer field might be named incorrectly and not match any attribute or key on the `dict` instance.\nOriginal exception text was: 'cost'."
您可以在注释前使用 .values()
按项目分组。
from django.db.models import Avg, Sum
Project.objects.values('project').annotate(
total_cost=Sum('cost'),
average_pct=Avg('physical_pct'),
)
关于您的更新,由于分组,成本字段不存在于查询集中。 .values()
和 .annotate()
之外的字段中的 None 将出现。要在序列化程序中使用总成本,您需要使用 SerializerMethodField()
.
class ProjectSerializer(serializers.ModelSerializer):
total_cost = serializers.SerializerMethodField()
class Meta:
model = Project
fields = ['project', 'total_cost']
def get_total_cost(self, instance):
return instance.total_cost
如果您想用总成本而不是分组来注释每个实例,并且您使用的是 Django >= 2.0,那么您可以执行以下操作。
from django.db.models import F, Q, Sum
Project.objects.annotate(total_cost=Sum('cost', filter=Q(project=F('project'))))