2016-02-28 109 views
2

我正在使用ModelViewSet通过get_queryset生成项目列表。我想返回一个带有对象列表和额外字段(DurationField的总和时间)的json。 例如:如何在Json中使用额外字段返回对象列表(Django Rest Framework)

{ 
    "total_time":"00:10:00", 
    "objects":[ 
     { 
     "pk":1, 
     "title":"Title", 
     "duration": "00:05:00" 
     }, 
     { 
     "pk":1, 
     "title":"Title", 
     "duration": "00:05:00" 
     } 
    ] 
} 

我该怎么做?下面是我的代码。

ModelViewSet:

class ModelViewSet(viewsets.ModelViewSet): 
    queryset = Model.objects.all() 
     serializer_class = ModelSerializer 
     permission_classes = (IsAuthenticated,) 

     def get_queryset(self): 
      user = self.request.user 
      list = Model.objects.filter(user=user) 
      total_time = .. ## sum the duration of list of objects 

      ## I want to return the list and total_time 
      return list 

serializers.py:

class ModelSerializer(serializers.ModelSerializer): 
      pk = serializers.IntegerField(read_only=True) 
      user = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), required=False, allow_null=True) 
      project = serializers.PrimaryKeyRelatedField(queryset=Project.objects.all(), required=False, allow_null=True) 
      class Meta: 
       model = Model 

       fields = ('pk', 'title', 'user', 'project', 'duration') 

网址:

router = DefaultRouter() 
router.register(r'^', views.ModelViewSet) 
urlpatterns = [ 
    url(r'^api', include(router.urls)), 
] 

回答

1

一种方法是子类的分页程序(默认分页类是PageNumberPagination)和调整get_paginated_response。这完全没有经过测试,但也许是这样的:

from rest_framework.pagination import PageNumberPagination 

class CustomPageNumberPagination(PageNumberPagination): 

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


class ModelViewSet(viewsets.ModelViewSet): 
    queryset = Model.objects.all() 
    serializer_class = ModelSerializer 
    permission_classes = (IsAuthenticated,) 
    pagination_class = CustomPageNumberPagination 

    def get_queryset(self): 
     user = self.request.user 
     list = Model.objects.filter(user=user) 

     self.total_time = .. ## sum the duration of list of objects 

     return list 

    def get_paginated_response(self, data): 
     return self.paginator.get_paginated_response(data, self.total_time) 

无论如何,希望这会有所帮助。

祝你好运!

+0

谢谢@CaffeineFueled!但我不知道这是否是最佳做法!我做了其他事情,我会很感激,如果你能让我知道你对代码的看法! –

0

最后我做到了!但我不确定这是否是最佳做法。如果有人有更好的主意,请分享!

class ModelJSONRenderer(JSONRenderer): 
    """ 
    Add "objects" and "total_time" in Json 
    """ 
    def render(self, data, accepted_media_type=None, renderer_context=None): 
     data = {'objects': data, 'total_time': renderer_context['total_time']} 
     return super(ModelJSONRenderer, self).render(data, accepted_media_type, renderer_context) 

ModelViewSet:

class ModelViewSet(viewsets.ModelViewSet): 
    queryset = Model.objects.all() 
     serializer_class = ModelSerializer 
     permission_classes = (IsAuthenticated,) 
    renderer_classes = (ModelJSONRenderer,) 

    def get_queryset(self): 
     user = self.request.user 
     list = Model.objects.filter(user=user) 

     self.total_time = .. ## sum the duration of list of objects 

     return list 

    def get_renderer_context(self): 
     """ 
     Returns a dict that is passed through to Renderer.render(), 
     as the `renderer_context` keyword argument. 
     """ 
     return { 
      'view': self, 
      'args': getattr(self, 'args',()), 
      'kwargs': getattr(self, 'kwargs', {}), 
      'request': getattr(self, 'request', None), 
      'total_time': self.total_time 
     } 
+0

我不确定在这种情况下是否有这样的事情是“最佳实践”。如果你发现一些适合你的东西,而且它不是非常复杂和/或不可能维护,那么我说它运行。可悲的是,我目前无法解决您的解决方案,但我认为这个概念听起来很合理。干杯! – CaffeineFueled

+0

再次感谢@CaffeineFueled;) –

相关问题