First things first, what you are currently doing is too complex without reason.
In order to achieve a "paginatable" queryset, it is preferred to change your owned_items() and dev_items() in simple filter combinations, rather than model methods. To clarify by example:
products = BaseItem.objects.filter(owner=request.user, owned=True)
instead of
products = BaseItem.objects.owned_items().filter(owner=request.user)
That way, you can produce a single queryset which will be easier to paginate:
user_items = BaseItem.objects.filter(
Q(owner=request.user, owned=True) |
Q(owner=request.user, dev=True)
)
Note 1: You can simplify things further if you like, but that gets out of scope of your question. As food for thought, check this out:
user_items = BaseItem.objects.filter(owner=request.user).distinct()
Note 2: You should use a single serializer for a single model because what you are doing adds complexity without benefit (high risk-low reward situation)
With the above mentioned and assumed:
There are some ways to achieve what you want here:
By utilizing GeneriAPIView and ListModelMixin you can refactor your class in such a way to have a .list() method with auto-pagination:
from rest_framework import mixins, generics
class ItemsAPIView(mixins.ListModelMixin, generics.GenericAPIView,):
permission_classes = (permissions.IsAuthenticated,)
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
serializer_class = OwnedItemSerializer
# You can define .get in here if you really need it.
# You can also override .list to add specific functionality
If you don't want to use the above, and you want to keep your APIView, then you can keep your get method and provide pagination for it as mentioned in this Q&A example:
class ItemsAPIView(APIView):
permission_classes = (permissions.IsAuthenticated,)
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
serializer_class = MyNewUnifiedSerializerClass
def get(self, request):
user_items = BaseItem.objects.filter(
owner=request.user
).distinct()
page = self.paginate_queryset(user_items)
if page is not None:
serializer = self.serializer_class(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(user_items, many=True)
return Response(serializer.data)
# Now add the pagination handlers taken from
# django-rest-framework/rest_framework/generics.py
@property
def paginator(self):
"""
The paginator instance associated with the view, or `None`.
"""
if not hasattr(self, '_paginator'):
if self.pagination_class is None:
self._paginator = None
else:
self._paginator = self.pagination_class()
return self._paginator
def paginate_queryset(self, queryset):
"""
Return a single page of results,
or `None` if pagination is disabled.
"""
if self.paginator is None:
return None
return self.paginator.paginate_queryset(
queryset,
self.request,
view=self
)
def get_paginated_response(self, data):
"""
Return a paginated style `Response` object
for the given output data.
"""
assert self.paginator is not None
return self.paginator.get_paginated_response(data)