【问题标题】:Get count of each item separately in a queryset Django DRF在查询集中 Django DRF 中分别获取每个项目的计数
【发布时间】:2019-06-10 22:43:04
【问题描述】:

我的目标是获取与每个Department 相关的Employee。例如,在 1 个部门工作 3 名员工,在 2 个部门工作另外 2 个员工。我想出了如何将所有Employee 计数为所有Employee.objects.values('department').annotate(emp_count_in_dep=Count('department')).order_by('department')

models.py:

class Department(models.Model):
    dep_name = models.CharField(max_length=100)

    def __str__(self):
        return self.dep_name


class Employee(models.Model):
    emp_name = models.CharField(max_length=100)
    department = models.ForeignKey(Department, on_delete=models.CASCADE)

    def __str__(self):
        return self.emp_name

views.py:

class DepartmentView(viewsets.ModelViewSet):

    queryset = Department.objects.all()
    serializer_class = DepartmentSerializer


class EmployeeView(viewsets.ModelViewSet):

    queryset = Employee.objects.all()
    serializer_class = EmployeeSerializer

serializers.py:

class DepartmentSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('dep_name', 'organization')
        model = Department

    def get_emp_count_for_dep(self, obj):
        emp_count_for_dep = Employee.objects.values('department').annotate(emp_count_in_dep=Count('department')).order_by('department')
        return emp_count_for_dep


class EmployeeSerializer(serializers.ModelSerializer):
    dep_count = serializers.SerializerMethodField()
    # emp_id = serializers.IntegerField(write_only=True)
    # emp_id = serializers.ReadOnlyField()
    emp_id = serializers.PrimaryKeyRelatedField(queryset=Employee.objects.all())

    class Meta:
        fields = ('emp_id', 'emp_name', 'department', 'dep_count')
        model = Employee

    def get_dep_count(self, obj, emp_id=emp_id):
        # dep_count = Department.objects.values('employee').get(pk=emp_id)
        dep_count = Department.objects.annotate(dep_count=Count('employee')).count()
        return dep_count

输出:

[
    {
        "dep_name": "second department",
        "emp_count_for_dep": [
            {
                "department": 1,
                "emp_count_in_dep": 3
            },
            {
                "department": 2,
                "emp_count_in_dep": 2
            }
        ]
    },
    {
        "dep_name": "first department",
        "emp_count_for_dep": [
            {
                "department": 1,
                "emp_count_in_dep": 3
            },
            {
                "department": 2,
                "emp_count_in_dep": 2
            }
        ]
    }
]

这段代码为每个Department 提供了所有Employee count() 的输出:

期望的输出: 但我需要 3 个用于第一个部门,2 个用于第二个部门......

[
    {
        "dep_name": "first department",
        "emp_count_for_dep": [
            {
                "department": 1,
                "emp_count_in_dep": 3
            }
        ]
    },
    {
        "dep_name": "second department",
        "emp_count_for_dep": [
            {
                "department": 2,
                "emp_count_in_dep": 2
            }
        ]
    }
]

如您所见,我尝试了不同的方法(使用 IntegerField 和 ReadOnlyField),还尝试了 self.instance.pk = 因为我需要 pk 因为我认为这有助于解决问题。我希望,重写get_dep_count 可以帮助我 - 例如添加一些参数,即pk(主键)。我尝试了以前的dep_count 定义(看上面的评论行。我留下它,因为它可能会帮助你帮助我)

【问题讨论】:

    标签: python django python-3.x django-rest-framework django-serializer


    【解决方案1】:

    如果您只想包含每个部门的员工人数,您可以替换它

    class DepartmentSerializer(serializers.ModelSerializer):
        class Meta:
            fields = ('dep_name', 'organization')
            model = Department
    
        def get_emp_count_for_dep(self, obj):
            emp_count_for_dep = Employee.objects.values('department').annotate(emp_count_in_dep=Count('department')).order_by('department')
            return emp_count_for_dep
    

    类似这样的东西

    class DepartmentSerializer(serializers.ModelSerializer):
    
        emp_count_for_dep = serializers.SerializerMethodField()
    
        class Meta:
            fields = ('dep_name', 'organization', 'emp_count_for_dep')
            model = Department
    
        def get_emp_count_for_dep(self, obj):
            return Employee.objects.filter(department=obj).count()
    

    【讨论】:

    • 哇!就是这么简单。为什么我要花 10 个小时来尝试了解如何去做……任何文档都以错误的方式引导我(我认为没有 pk 无法实现这些)。谢谢你,@dalvtor - 这个答案真的是我需要的!我现在很开心)
    • 我很乐意提供帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 2011-07-23
    • 2022-01-26
    • 2015-11-13
    • 2020-12-06
    • 2023-03-30
    • 2021-07-10
    相关资源
    最近更新 更多