Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(pagination)!: Use PAGINATION_DEFAULT_LIMIT when limit is not provided #673

Merged
merged 2 commits into from
Dec 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions strawberry_django/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,22 @@
from strawberry_django.resolvers import django_resolver

from .arguments import argument
from .settings import strawberry_django_settings

NodeType = TypeVar("NodeType")
_QS = TypeVar("_QS", bound=QuerySet)

PAGINATION_ARG = "pagination"


@strawberry.input
class OffsetPaginationInput:
offset: int = 0
limit: Optional[int] = None


@strawberry.type
class OffsetPaginationInfo:
offset: int = 0
limit: Optional[int] = None
limit: Optional[int] = UNSET


@strawberry.input
class OffsetPaginationInput(OffsetPaginationInfo): ...


@strawberry.type
Expand Down Expand Up @@ -142,8 +141,13 @@ def apply(
)
else:
start = pagination.offset
if pagination.limit is not None and pagination.limit >= 0:
stop = start + pagination.limit
limit = pagination.limit
if limit is UNSET:
settings = strawberry_django_settings()
limit = settings["PAGINATION_DEFAULT_LIMIT"]

if limit is not None and limit >= 0:
stop = start + limit
queryset = queryset[start:stop]
else:
queryset = queryset[start:]
Expand All @@ -165,7 +169,7 @@ def apply_window_pagination(
*,
related_field_id: str,
offset: int = 0,
limit: Optional[int] = None,
limit: Optional[int] = UNSET,
) -> _QS:
"""Apply pagination using window functions.

Expand Down Expand Up @@ -204,6 +208,10 @@ def apply_window_pagination(
if offset:
queryset = queryset.filter(_strawberry_row_number__gt=offset)

if limit is UNSET:
settings = strawberry_django_settings()
limit = settings["PAGINATION_DEFAULT_LIMIT"]

# Limit == -1 means no limit. sys.maxsize is set by relay when paginating
# from the end to as a way to mimic a "not limit" as well
if limit is not None and limit >= 0 and limit != sys.maxsize:
Expand Down
2 changes: 1 addition & 1 deletion tests/projects/snapshots/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ type OffsetPaginationInfo {

input OffsetPaginationInput {
offset: Int! = 0
limit: Int = null
limit: Int
}

type OperationInfo {
Expand Down
2 changes: 1 addition & 1 deletion tests/projects/snapshots/schema_with_inheritance.gql
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ type OffsetPaginationInfo {

input OffsetPaginationInput {
offset: Int! = 0
limit: Int = null
limit: Int
}

type OperationInfo {
Expand Down
74 changes: 72 additions & 2 deletions tests/test_paginated_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import pytest
import strawberry
from django.db.models import QuerySet
from django.test.utils import override_settings

import strawberry_django
from strawberry_django.optimizer import DjangoOptimizerExtension
from strawberry_django.pagination import OffsetPaginated, OffsetPaginationInput
from strawberry_django.settings import StrawberryDjangoSettings
from tests import models


Expand Down Expand Up @@ -69,7 +71,7 @@ class Query:

input OffsetPaginationInput {
offset: Int! = 0
limit: Int = null
limit: Int
}
bellini666 marked this conversation as resolved.
Show resolved Hide resolved

type Query {
Expand Down Expand Up @@ -630,7 +632,7 @@ def fruits_with_order_and_filter(self) -> QuerySet[models.Fruit]: ...

input OffsetPaginationInput {
offset: Int! = 0
limit: Int = null
limit: Int
}

type Query {
Expand Down Expand Up @@ -900,3 +902,71 @@ def fruits_with_order_and_filter(
],
},
}


@pytest.mark.django_db(transaction=True)
@override_settings(
STRAWBERRY_DJANGO=StrawberryDjangoSettings( # type: ignore
PAGINATION_DEFAULT_LIMIT=2,
),
)
def test_pagination_default_limit():
@strawberry_django.type(models.Fruit)
class Fruit:
id: int
name: str

@strawberry.type
class Query:
fruits: OffsetPaginated[Fruit] = strawberry_django.offset_paginated()

models.Fruit.objects.create(name="Apple")
models.Fruit.objects.create(name="Banana")
models.Fruit.objects.create(name="Strawberry")
models.Fruit.objects.create(name="Watermelon")

schema = strawberry.Schema(query=Query)

query = """\
query GetFruits ($pagination: OffsetPaginationInput) {
fruits (pagination: $pagination) {
totalCount
results {
name
}
}
}
"""

res = schema.execute_sync(query)
assert res.errors is None
assert res.data == {
"fruits": {
"totalCount": 4,
"results": [{"name": "Apple"}, {"name": "Banana"}],
}
}

res = schema.execute_sync(query, variable_values={"pagination": {"offset": 1}})
assert res.errors is None
assert res.data == {
"fruits": {
"totalCount": 4,
"results": [{"name": "Banana"}, {"name": "Strawberry"}],
}
}

# Setting limit to None should return all results
res = schema.execute_sync(query, variable_values={"pagination": {"limit": None}})
assert res.errors is None
assert res.data == {
"fruits": {
"totalCount": 4,
"results": [
{"name": "Apple"},
{"name": "Banana"},
{"name": "Strawberry"},
{"name": "Watermelon"},
],
}
}
Loading