DRF Cursor Pagination with ContentType framework in List view

532 Views Asked by At

I'm using Django-Rest-Framework's cursor pagination class as well as Django's ContentType framework. I have some models that basically (handwriting these) look like these:

from django.contrib.contentypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
class CombinedModel(models.Model):
    id = models.UUIDField(default=uuid4(), primary_key=True)
    created = models.DateTimeField(auto_now_add=True)
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = BigIntegerField()
    content_object = GenericForeignKey()

class Amodel(models.Model):
    stuff = models.CharField(max_length=100)

Now I want to be able to paginate the CombinedModel using a generic view set. The problem arises with the cursor pagination being unable to get the stuff data when accessing the AModel through content_object.

So this is what I have for a viewset and cursor pagination so far (that is failing):

from rest_framework.pagination import CursorPagination

class MyObject(object):
    def __init__(self, content_type, object_id, stuff):
        self.content_type = content_type
        self.object_id = object_id
        self.stuff = stuff

class MySerializer(serializer.Serializer):
    content_type = serializer.CharField(max_length=20)
    object_id = serializer.IntegerField()
    stuff = serializer.CharField(max_length=100)

class CursorSetPagination(CursorPagination):
    page_size = 5
    page_size_query_param = "page_size"
    ordering = "-created"

    def get_paginated_response(self, data):
        items = []
        for x in data:
            model_name = x.content_type.model.capitalize()
            items.append(MyObject(content_type=model_name, object_id=x.object_id, stuff=x.content_object.stuff))
        serializer = MySerializer(items, many=True)
        return Response({'results': serializer.data}) 

There should also be the next cursor and the number of pages left or at least the page count and current page but I can't seem to access it

class CombinedViewSet(viewsets.GenericViewSet):
    pagination_class = CursorSetPagination
    serializer_class = MySerializer

    def get_queryset(self):
        return CombinedModel.objects.all()

    def list(self, request):
        return self.get_paginated_response(self.get_queryset())

There are multiple problems:

  1. The data I send in the list function is the entire queryset, not the "paginated" queryset that I'm looking to do
  2. I'm unable to access the stuff attribute from the content_object from the parameter data in the get_paginated_response function.
  3. I'm not sure how to get the next cursor, the current page, the number of pages left, etc.

Helping with any of these issues is greatly appreciated!! (I know using GenericFKs is terrible, but it is of utmost importance for my situation. I specifically designed the DB to use it).

0

There are 0 best solutions below