首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DRF:聚合相似条目名称

DRF:聚合相似条目名称
EN

Stack Overflow用户
提问于 2019-09-03 14:52:08
回答 1查看 84关注 0票数 0

我想按名称合并条目,并在它们的其他字段中执行附加操作。

在本例中,我希望获得具有相同项目名称的条目的total_cost和average_pct。

假设:

代码语言:javascript
复制
# 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个条目:

代码语言:javascript
复制
[
    {
        "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
    }
]

我想要的输出:

代码语言:javascript
复制
[
    {
        "project": "Project-X",
        "average_pct": 79,
        "total_cost": 3000.00
    },
    {
        "project": "Project-Y",
        "average_pct": 73,
        "total_cost": 560.00
    }
]

更新1:

值()的前提下,它必须根据字段参数按相似项进行分组。然而,当我尝试的时候:

代码语言:javascript
复制
# 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

我收到一个错误:

代码语言:javascript
复制
"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'."
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-03 17:09:10

您可以在注释之前使用.values()按项目分组。

代码语言:javascript
复制
from django.db.models import Avg, Sum

Project.objects.values('project').annotate(
    total_cost=Sum('cost'),
    average_pct=Avg('physical_pct'),
)

对于您的更新,由于分组的原因,queryset中没有成本字段。.values().annotate()以外的字段都不会出现。要在序列化程序中使用总成本,需要使用SerializerMethodField()

代码语言:javascript
复制
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,那么您可以执行以下操作。

代码语言:javascript
复制
from django.db.models import F, Q, Sum

Project.objects.annotate(total_cost=Sum('cost', filter=Q(project=F('project'))))
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57774159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档