向Django Rest Framework结果添加额外数据以获得整个结果集

Tom*_*eld 25 python django django-rest-framework

我正在使用Django Rest Framework,需要在结果集中添加额外的数据.具体来说,你通常会在哪里:

{
    "count": 45, 
    "next": "http://localhost:8000/foo/bar?page=2", 
    "previous": null, 
    "results": [
        {...}
    ]
}
Run Code Online (Sandbox Code Playgroud)

我想添加额外的计数如下:

{
    "count": 45,
    "10_mi_count": 10,
    "20_mi_count": 30,
    "30_mi_count": 45,
    "next": "http://localhost:8000/foo/bar?page=2", 
    "previous": null, 
    "results": [
        {...}
    ]
}
Run Code Online (Sandbox Code Playgroud)

此示例中的额外计数只是有多少对象的字段距离,其值小于键中描述的英里数.

我的问题是我不知道扩展和插入此行为的最佳位置在哪里.

理想情况下,无论结果是否分页,我都希望这样做,不作任何假设.

我真正追求的是向正确的方向点头(为什么这是正确的地方).

我已经检查了文档,找不到任何描述如何添加这样的东西的东西,但我很高兴在这个分数上被证明是错误的.

小智 31

由于您似乎正在使用Rest Framework中的一个ListView,您可以覆盖类中的list()方法并在结果数据上设置新值,如下所示:

    def list(self, request, *args, **kwargs):
        response = super().list(request, args, kwargs)
        # Add data to response.data Example for your object:
        response.data['10_mi_count'] = 10 # Or wherever you get this values from
        response.data['20_mi_count'] = 30
        response.data['30_mi_count'] = 45
        return response
Run Code Online (Sandbox Code Playgroud)

请注意,您的类必须直接或通过Rest Framework API(http://www.django-rest-framework.org/api-guide/generic-views#listmodelmixin)中的GenericView继承ListModelMixin .我真的不知道这是否是正确的方法,但这是一个快速解决方案.

希望能帮助到你!


Tom*_*eld 5

最后,我刚刚创建了一个自定义分页序列化器,其字段如下所示:

class DistanceCountField(serializers.Field):
    def to_native(self, value):
        try:
            distance_counts = {
                '1_mile': self._count_lte_miles(value, 1),
                '5_mile': self._count_lte_miles(value, 5),
                '10_mile': self._count_lte_miles(value, 10),
                '20_mile': self._count_lte_miles(value, 20),
            }
        except FieldError:
            distance_counts = None

        return distance_counts

    def _count_lte_miles(self, value, miles):
        meters = miles * 1609.344
        return value.filter(distance__lte=meters).count()


class PaginatedCountSerializer(pagination.PaginationSerializer):
    distance_counts = DistanceCountField(source='paginator.object_list')

    class Meta:
        # Class omitted, just a standard model serializer
        object_serializer_class = MyModelSerializer 
Run Code Online (Sandbox Code Playgroud)

我还为查询集中的每个对象添加了距离注释,以便进行过滤。


use*_*488 5

使用此解决方案中提到的SerializerMethodField

它可以用于将任何类型的数据添加到对象的序列化表示中。(REST框架文档

文档中的示例:

from django.contrib.auth.models import User
from django.utils.timezone import now
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    days_since_joined = serializers.SerializerMethodField()

    class Meta:
        model = User

    def get_days_since_joined(self, obj):
        return (now() - obj.date_joined).days
Run Code Online (Sandbox Code Playgroud)