Skip to content

Commit 88b63db

Browse files
authored
Merge pull request #69 from eadwinCode/ninja_pagination_response_schema_fix
Ninja pagination response schema fix
2 parents 0b2a6a8 + af5c073 commit 88b63db

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

ninja_extra/schemas/response.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from ninja import Schema
55
from ninja.constants import NOT_SET
6+
from pydantic import validator
67
from pydantic.generics import GenericModel
78
from pydantic.main import BaseModel
89
from pydantic.networks import AnyHttpUrl
@@ -86,6 +87,12 @@ class NinjaPaginationResponseSchema(
8687
):
8788
items: List[T]
8889

90+
@validator("items", pre=True)
91+
def validate_items(cls, value: Any) -> Any:
92+
if value and not isinstance(value, list):
93+
return list(value)
94+
return value
95+
8996
NinjaPaginationResponseSchema.__generic_model__ = NinjaPaginationResponseSchema
9097

9198
class IdSchema(GenericModel, Generic[T], Schema):

tests/test_pagination.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import inspect
2+
import typing
3+
from abc import abstractmethod
4+
from typing import Sequence, overload
25

36
import django
47
import pytest
@@ -14,11 +17,27 @@
1417
PaginatorOperation,
1518
paginate,
1619
)
20+
from ninja_extra.schemas import NinjaPaginationResponseSchema
1721
from ninja_extra.testing import TestAsyncClient, TestClient
1822

1923
ITEMS = list(range(100))
2024

2125

26+
class FakeQuerySet(typing.Sequence):
27+
def __init__(self, items=None):
28+
self.items = items or ITEMS
29+
30+
def __getitem__(self, index: int) -> typing.Any:
31+
return FakeQuerySet(self.items[index])
32+
33+
def __len__(self) -> int:
34+
return len(self.items)
35+
36+
def __iter__(self):
37+
for item in self.items:
38+
yield item
39+
40+
2241
class CustomPagination(PaginationBase):
2342
# only offset param, defaults to 5 per page
2443
class Input(Schema):
@@ -36,11 +55,11 @@ class SomeAPIController:
3655
def items_1(self):
3756
return ITEMS
3857

39-
@route.get("/items_2")
58+
@route.get("/items_2", response=NinjaPaginationResponseSchema[int])
4059
@paginate() # with brackets (should use default pagination)
4160
def items_2(self, someparam: int = 0):
4261
# also having custom param `someparam` - that should not be lost
43-
return ITEMS
62+
return FakeQuerySet()
4463

4564
@route.get("/items_3")
4665
@paginate(CustomPagination, pass_parameter="pass_kwargs")

0 commit comments

Comments
 (0)