Skip to content

Instantly share code, notes, and snippets.

@amzar96
Created December 5, 2023 01:09
Show Gist options
  • Save amzar96/ae6caf3c5afc54c02da97089bc68d964 to your computer and use it in GitHub Desktop.
Save amzar96/ae6caf3c5afc54c02da97089bc68d964 to your computer and use it in GitHub Desktop.
Pagination with Django Ninja
'''
Credit to https://github.com/vitalik/django-ninja/issues/104#issuecomment-805939752 🔥
python '3.11.6'
django '4.2.7'
ninja '1.0.1'
pydantic '2.5.2'
'''
from ninja import Router
from typing import Optional
from datetime import datetime
from django.core.paginator import Page, Paginator
def replace_query_param(url, key, val):
from urllib import parse
from django.utils.encoding import force_str
(scheme, netloc, path, query, fragment) = parse.urlsplit(force_str(url))
query_dict = parse.parse_qs(query, keep_blank_values=True)
query_dict[force_str(key)] = [force_str(val)]
query = parse.urlencode(sorted(query_dict.items()), doseq=True)
return parse.urlunsplit((scheme, netloc, path, query, fragment))
def get_next_page_url(request, page: Page) -> Optional[str]:
if not page.has_next():
return None
return replace_query_param(request.build_absolute_uri(), "page", page.number + 1)
def get_previous_page_url(request, page: Page) -> Optional[str]:
if not page.has_previous():
return None
return replace_query_param(request.build_absolute_uri(), "page", page.number - 1)
router = Router()
@router.get(
"/users",
response=ListStdResponse[Union[UserSchema, None]],
)
def list_users(request, page: int = 1, limit: int = 5):
users = model.User.objects.all()
paginator_page = Paginator(users, per_page=limit).get_page(page)
users = [user for user in paginator_page.object_list]
next_page = get_next_page_url(request, paginator_page).__str__()
previous_page = get_previous_page_url(request, paginator_page).__str__()
return {
"data": users,
"count": paginator_page.paginator.count,
"next": next_page,
"previous": previous_page,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment