Django Rest Framework:序列化程序方法字段的总和



我无法让它工作。我有以下序列化程序:

class OwnArbeitstagListSerializer(serializers.ModelSerializer):
stundensumme = serializers.SerializerMethodField()
class Meta:
model = Arbeitstag
ordering = ['-datum']
fields = ('id', 'datum', 'in_abrechnung', 'stundensumme')
depth=0
def get_stundensumme(self, obj):
return Stunden.objects.filter(arbeitstagid=obj.id).aggregate(Sum('stunden'))['stunden__sum']

.. 返回每天的工作时间总和(该模型名为"工作日"(。到目前为止,这很有效。现在,我想让模型视图集返回工作日列表:

class OwnArbeitstagListViewSet(viewsets.ReadOnlyModelViewSet):
filter_class = ArbeitstagListFilter
filter_fields = ('datum',)
filter_backends = (DjangoFilterBackend, filters.OrderingFilter, filters.SearchFilter,)
ordering =["-datum"]
serializer_class = OwnArbeitstagListSerializer
def get_queryset(self):
return Arbeitstag.objects.filter(userid=self.request.user.id)

你看,我正在按用户和日期(使用过滤器后端(过滤它。但是现在,我想有一个额外的字段,它给了我序列化器方法字段"stundensumme"的总和。它是一笔总和。它应该只计算显示对象的总和(应用了日期过滤器(。

我遇到了麻烦,因为(我假设(Seriealizermethod字段仅在序列化时计算,我想获取我的总和值已经晚了。我已经尝试过这个,但它找不到序列化器方法字段"stundensumme"来计算以下各项的总和:

class CustomPageNumberPagination(PageNumberPagination):
def get_paginated_response(self, data, summe):
return Response(OrderedDict([
('count', self.page.paginator.count),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('summe', summe),
('results', data)
]))

class OwnArbeitstagListViewSet(viewsets.ReadOnlyModelViewSet):
pagination_class = CustomPageNumberPagination
filter_class = ArbeitstagListFilter
filter_fields = ('datum',)
filter_backends = (DjangoFilterBackend, filters.OrderingFilter, filters.SearchFilter,)
ordering =["-datum"]
serializer_class = OwnArbeitstagListSerializer
def get_queryset(self):
arbeitstag = Arbeitstag.objects.all().filter(userid=self.request.user.id)
return arbeitstag
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
self.summe = queryset.aggregate(Sum('stundensumme'))['stundensumme__sum']
return super().list(request, *args, **kwargs)
def get_paginated_response(self, data):
return self.paginator.get_paginated_response(data, self.summe)

如果你看一下list()方法实现,你会发现这个:

"""
List a queryset.
"""
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)

您的猜测是正确的stundensumme字段只会被序列化所吸引,因此您有两个选择:

  1. 使用 anotate(( 并将其添加到 你的 defiendget_queryset()这样每个对象都会有该字段,你不需要在序列化程序上为该字段提供实现,你只需像你一样在 fields 属性中添加字段

  2. get_paginated_response()data做你的求和,因为它是由序列化程序重新设置的列表,因此你可以很容易地操作它,例如:

    def get_summe(自我,数据(:

    sum = 0
    for item in data:
    sum += item['stundensumme']
    return
    

并简单地使用它

def get_paginated_response(self, data):
return Response(OrderedDict([
('count', self.page.paginator.count),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('summe', self.get_summe(data)),
('results', data)
]))

并且不要忘记删除您添加的额外代码,因为我们不需要两种方式

最新更新