Skip to content

Commit

Permalink
Merge pull request #1134 from kajiczech/kc-add-max-limit-to-input-schema
Browse files Browse the repository at this point in the history
Update LimitOffsetPagination.Input schema
  • Loading branch information
vitalik committed Apr 24, 2024
2 parents 72d9871 + b010ba2 commit 3c0cc93
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 1 deletion.
9 changes: 8 additions & 1 deletion ninja/pagination.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import inspect
from abc import ABC, abstractmethod
from functools import partial, wraps
from math import inf
from typing import Any, Callable, List, Optional, Tuple, Type

from django.db.models import QuerySet
Expand Down Expand Up @@ -55,7 +56,13 @@ def _items_count(self, queryset: QuerySet) -> int:

class LimitOffsetPagination(PaginationBase):
class Input(Schema):
limit: int = Field(settings.PAGINATION_PER_PAGE, ge=1)
limit: int = Field(
settings.PAGINATION_PER_PAGE,
ge=1,
le=settings.PAGINATION_MAX_LIMIT
if settings.PAGINATION_MAX_LIMIT != inf
else None,
)
offset: int = Field(0, ge=0)

def paginate_queryset(
Expand Down
77 changes: 77 additions & 0 deletions tests/test_pagination.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import importlib
from typing import Any, List

import pytest
from django.test import override_settings

from ninja import NinjaAPI, Schema
from ninja.errors import ConfigError
Expand Down Expand Up @@ -324,6 +326,81 @@ def test_case9():
}


@override_settings(NINJA_PAGINATION_MAX_LIMIT=1000)
def test_10_max_limit_set():
# reload to apply django settings
from ninja import conf, pagination

importlib.reload(conf)
importlib.reload(pagination)
new_api = NinjaAPI()
new_client = TestClient(new_api)

@new_api.get("/items_10", response=List[int])
@paginate # LimitOffsetPagination is set as default
def items_10(request, **kwargs):
return ITEMS

response = new_client.get("/items_10?limit=1000").json()
assert response == {"items": ITEMS[:1000], "count": 100}

schema = new_api.get_openapi_schema()["paths"]["/api/items_10"]["get"]
# print(schema)
assert schema["parameters"] == [
{
"in": "query",
"name": "limit",
"schema": {
"title": "Limit",
"default": 100,
"minimum": 1,
"maximum": 1000,
"type": "integer",
},
"required": False,
},
{
"in": "query",
"name": "offset",
"schema": {
"title": "Offset",
"default": 0,
"minimum": 0,
"type": "integer",
},
"required": False,
},
]


@override_settings(NINJA_PAGINATION_MAX_LIMIT=1000)
def test_11_max_limit_set_and_exceeded():
# reload to apply django settings
from ninja import conf, pagination

importlib.reload(conf)
importlib.reload(pagination)
new_api = NinjaAPI()
new_client = TestClient(new_api)

@new_api.get("/items_11", response=List[int])
@paginate # LimitOffsetPagination is set as default
def items_11(request, **kwargs):
return ITEMS

response = new_client.get("/items_11?limit=1001").json()
assert response == {
"detail": [
{
"ctx": {"le": 1000},
"loc": ["query", "limit"],
"msg": "Input should be less than or equal to 1000",
"type": "less_than_equal",
}
]
}


def test_config_error_None():
with pytest.raises(ConfigError):

Expand Down

0 comments on commit 3c0cc93

Please sign in to comment.