简体   繁体   English

用于计数对象的 Django 模型 ListAPIView 序列化程序

[英]Django Model ListAPIView serializer for counting objects

I have a model as follows, Entity :我有一个模型如下,实体:

class Entity(models.Model):
    uuid          = models.CharField(max_length=12, default=None)
    description   = models.CharField(max_length=255, default="")

I want to provide a serialization for the all entity objects where the response will provide the count of each description type that is available in the database.我想为所有实体对象提供序列化,其中响应将提供数据库中可用的每个描述类型的计数。

For instance, the table has the following content:例如,该表具有以下内容:

1.cat 2.dog 3.cat 4.dog 5.bird 6.bird 7.dog 1.猫 2.狗 3.猫 4.狗 5.鸟 6.鸟 7.狗

The serialization will be :序列化将是:

dog : 3 cat : 2 bird :2狗:3 猫:2 鸟:2

How should I modify the following serializer code to make this happen ?我应该如何修改以下序列化程序代码来实现这一点?

#Entity Count(per Intelligence) Search
class EntityFilterSerializer(serializers.ModelSerializer):

    class Meta:
        model = Entity
        fields = ('description')

class StandardResultsSetPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'
    max_page_size = 100

class EntityList(generics.ListAPIView):
    model = Entity
    serializer_class = EntityFilterSerializer
    filter_backends = [filters.SearchFilter]
    queryset = Entity.objects.order_by('id')
    search_fields = ['=uuid', ]
    pagination_class = StandardResultsSetPagination

The problem is more about getting the data than serializing it.问题更多是关于获取数据而不是序列化数据。 Since keys in your example response are not fixed, creating a Serializer would be problematic and actually not required.由于您的示例响应中的键不是固定的,因此创建 Serializer 会出现问题,实际上不需要。 You probably do not need pagination for this view.您可能不需要此视图的分页。 Anyway, that's how I would have implemented it:无论如何,这就是我实施它的方式:

 class EntityList(generics.ListAPIView):
    model = Entity
    filter_backends = [filters.SearchFilter]
    search_fields = ['uuid']

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        description_counts = queryset.order_by().values('description').annotate(
            count=Count('*')
        )
        return Response({
            d['description']: d['count']
            for d in description_counts
        })

It will break swagger if you are using one, if that's the case you would have to provide "some" serializer_class to fix it.如果您正在使用它,它将打破招摇,如果是这种情况,您将不得不提供“一些” serializer_class 来修复它。 I prefer to use this beauty.我更喜欢用这种美。 You can write the description of an actual response in the docstring.您可以在文档字符串中写入实际响应的描述。

class EmptySerializer(serializers.Serializer):
    pass

Alternatively, you can decide to alter the format of the response, and it can be actually preferred by your frontend developers.或者,您可以决定更改响应的格式,您的前端开发人员实际上可能更喜欢它。

[{"description": "cat", "count": 5}, {"description": "dog", "count": 2}]

For this format, you can easily describe a serializer对于这种格式,您可以轻松描述序列化程序

class CountsSerializer(serializers.Serializer):
    description = serializers.CharField()
    count = serializers.IntegerField()

class EntityList(generics.ListAPIView):
    model = Entity
    filter_backends = [filters.SearchFilter]
    serializer_class = CountsSerializer

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        description_counts = queryset.order_by().values('description').annotate(
            count=Count('*')
        )
        serializer = self.get_serializer(description_counts, many=True)
        return Response(serializer.data)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM