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.