2016-02-28 106 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;) –

相關問題