How to use pagination with djangochannelsrestframework?

I'm using djangochannelsrestframework for my project and want to use Pagination. I found the PaginatedModelListMixin.

This is my consumer:

class UserConsumer(GenericAsyncModelAPIConsumer):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    pagination_class = WebsocketPageNumberPagination

    @model_observer(User)
    async def user_activity(self, message, observer=None, **kwargs):
        await self.send_json(message)

    @user_activity.serializer
    def user_activity_serializer(self, instance, action, **kwargs):
        return {
            "action": action.value,
            "data": UserSerializer(instance).data,
        }

    async def connect(self):
        await self.accept()
        await self.user_activity.subscribe()

The GenericAsyncModelAPIConsumer is just a wrapper for all the CRUD mixins

class GenericAsyncModelAPIConsumer(
    PaginatedModelListMixin,
    CreateModelMixin,
    UpdateModelMixin,
    RetrieveModelMixin,
    DeleteModelMixin,
    GenericAsyncAPIConsumer,
):
    pass

The WebsocketPageNumberPagination should be a wrapper for the rest_framework's PageNumberPagination, but it didn't work for me.

I send the request with a js WebSocket like this:

class ModelWebSocket extends WebSocket {
  items = reactive([])

  
  constructor(url, protocols, pk = 'id') {
    // Call the parent constructor
    super(url, protocols)

    // List all items when the connection is opened
    this.onopen = () => {
      console.debug('[WS] Connected')
      this.list()
    }

    // Handle incoming messages
    this.onmessage = (event) => {
      const message = JSON.parse(event.data)

      console.log('[WS] Message', message)

      // Some more stuff, but the message is the interessting
    }

    // Close and error handling
    // ...
  }

  list() {
    return new Promise((resolve, reject) => {
      const requestId = this.#getAndSetPendingRequest(resolve, reject)
      this.send(
        JSON.stringify({
          action: 'list',
          request_id: requestId,
          page_size: 1, // just for testing, will be an attribute later
          page: 1,
        })
      )
    })
  }

  // ...
}

The #getAndSetPendingRequest can be ignored, that's just for housekeeping of the requets.

My current approch is to pass the kwargs as request.query_params:

class WebsocketPageNumberPagination(PageNumberPagination):
    """
    Pagination class that supports djangochannelsrestframework's additional parameters.
    """

    def paginate_queryset(self, queryset, request=None, **kwargs):
        kwargs.pop("view", None)
        kwargs.pop("request_id", None)
        request["query_params"] = kwargs
        # Call the parent method
        return super().paginate_queryset(queryset, request)

That give no errors, but it also does not paginate the results, just give me the list of data like the ListModelMixin

The documantions of djangochannelsrestframework say nothing about the usage of the PaginatedModelListMixin, and I also doesn't find any examples of online. AI Bots wants to write my an own pagination, but thats not my favorite solution.

In fact, I would like that the pagination works like the works in the rest_framework pagination. I set a page_size and page number and get the results for that page together with the metadata like the count of all objects. The best would be that if the websocket only notifys about changes of models on the current page.

Вернуться на верх