diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 8d0bf284a..01d00b3b9 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -172,12 +172,12 @@ class GenericAPIView(views.APIView): return None return self.paginator.paginate_queryset(queryset, self.request, view=self) - def get_paginated_response(self, data): + def get_paginated_response(self, data, extra_fields={}): """ Return a paginated style `Response` object for the given output data. """ assert self.paginator is not None - return self.paginator.get_paginated_response(data) + return self.paginator.get_paginated_response(data, extra_fields) # Concrete view classes that provide method handlers diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py index f3695e665..77097a06e 100644 --- a/rest_framework/mixins.py +++ b/rest_framework/mixins.py @@ -42,7 +42,11 @@ class ListModelMixin(object): page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) - return self.get_paginated_response(serializer.data) + if 'extra_fields' in kwargs: + extra_fields = kwargs['extra_fields'] + else: + extra_fields = {} + return self.get_paginated_response(serializer.data, extra_fields) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index 0255cfc7f..5d36b8edd 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -149,7 +149,7 @@ class BasePagination(object): def paginate_queryset(self, queryset, request, view=None): # pragma: no cover raise NotImplementedError('paginate_queryset() must be implemented.') - def get_paginated_response(self, data): # pragma: no cover + def get_paginated_response(self, data, extra_fields={}): # pragma: no cover raise NotImplementedError('get_paginated_response() must be implemented.') def to_html(self): # pragma: no cover @@ -225,13 +225,19 @@ class PageNumberPagination(BasePagination): self.request = request return list(self.page) - def get_paginated_response(self, data): - return Response(OrderedDict([ + def get_paginated_dictionary(self, data): + return OrderedDict([ ('count', self.page.paginator.count), ('next', self.get_next_link()), ('previous', self.get_previous_link()), ('results', data) - ])) + ]) + + def get_paginated_response(self, data, extra_fields={}): + ordered_dict = self.get_paginated_dictionary(data) + for key in extra_fields: + ordered_dict.__setitem__(key, extra_fields[key]) + return Response(ordered_dict) def get_page_size(self, request): if self.page_size_query_param: @@ -346,13 +352,19 @@ class LimitOffsetPagination(BasePagination): return [] return list(queryset[self.offset:self.offset + self.limit]) - def get_paginated_response(self, data): - return Response(OrderedDict([ + def get_paginated_dictionary(self, data): + return OrderedDict([ ('count', self.count), ('next', self.get_next_link()), ('previous', self.get_previous_link()), ('results', data) - ])) + ]) + + def get_paginated_response(self, data, extra_fields={}): + ordered_dict = self.get_paginated_dictionary(data) + for key in extra_fields: + ordered_dict.__setitem__(key, extra_fields[key]) + return Response(ordered_dict) def get_limit(self, request): if self.limit_query_param: @@ -758,12 +770,18 @@ class CursorPagination(BasePagination): attr = getattr(instance, field_name) return six.text_type(attr) - def get_paginated_response(self, data): - return Response(OrderedDict([ + def get_paginated_dictionary(self, data): + return OrderedDict([ ('next', self.get_next_link()), ('previous', self.get_previous_link()), ('results', data) - ])) + ]) + + def get_paginated_response(self, data, extra_fields={}): + ordered_dict = self.get_paginated_dictionary(data) + for key in extra_fields: + ordered_dict.__setitem__(key, extra_fields[key]) + return Response(ordered_dict) def get_html_context(self): return {