Fix pagination for 'last' page.

This commit is contained in:
Paul Craciunoiu 2020-12-15 14:58:02 -07:00
parent 4c0c821b74
commit 4469cf3d09
3 changed files with 60 additions and 7 deletions

View File

@ -147,21 +147,19 @@ class DjangoConnectionField(ConnectionField):
if isinstance(iterable, QuerySet): if isinstance(iterable, QuerySet):
list_length = iterable.count() list_length = iterable.count()
list_slice_length = (
min(max_limit, list_length) if max_limit is not None else list_length
)
else: else:
list_length = len(iterable) list_length = len(iterable)
list_slice_length = (
min(max_limit, list_length) if max_limit is not None else list_length list_slice_length = list_length
) if max_limit is not None and "last" not in args:
list_slice_length = min(max_limit, list_length)
# If after is higher than list_length, connection_from_list_slice # If after is higher than list_length, connection_from_list_slice
# would try to do a negative slicing which makes django throw an # would try to do a negative slicing which makes django throw an
# AssertionError # AssertionError
after = min(get_offset_with_default(args.get("after"), -1) + 1, list_length) after = min(get_offset_with_default(args.get("after"), -1) + 1, list_length)
if max_limit is not None and "first" not in args: if max_limit is not None and "first" not in args and "last" not in args:
args["first"] = max_limit args["first"] = max_limit
connection = connection_from_list_slice( connection = connection_from_list_slice(

View File

@ -67,6 +67,9 @@ class Reporter(models.Model):
def some_method(self): def some_method(self):
return 123 return 123
class Meta:
ordering = ("id",)
class CNNReporterManager(models.Manager): class CNNReporterManager(models.Manager):
def get_queryset(self): def get_queryset(self):

View File

@ -727,6 +727,58 @@ def test_should_error_if_last_is_greater_than_max(graphene_settings):
assert result.data == expected assert result.data == expected
def test_should_return_last_page_if_more_than_max_limit(graphene_settings):
graphene_settings.RELAY_CONNECTION_MAX_LIMIT = 4
class ReporterType(DjangoObjectType):
class Meta:
model = Reporter
interfaces = (Node,)
class Query(graphene.ObjectType):
all_reporters = DjangoConnectionField(ReporterType)
assert Query.all_reporters.max_limit == 4
reporters = [Reporter(**kwargs) for kwargs in REPORTERS]
Reporter.objects.bulk_create(reporters)
r = Reporter.objects.create(
first_name="John", last_name="Doe", email="johndoe@example.com", a_choice=1
)
r2 = Reporter.objects.create(
first_name="Jane", last_name="Doe", email="janedoe@example.com", a_choice=2
)
schema = graphene.Schema(query=Query)
query = """
query NodeFilteringQuery {
allReporters(last: 2) {
edges {
node {
id
}
}
}
}
"""
expected = {
"allReporters": {
"edges": [
{"node": {"id": to_global_id("ReporterType", r.id)}},
{"node": {"id": to_global_id("ReporterType", r2.id)}},
]
}
}
result = schema.execute(query)
assert not result.errors
assert len(result.data["allReporters"]["edges"]) == 2
assert result.data == expected
def test_should_query_promise_connectionfields(): def test_should_query_promise_connectionfields():
from promise import Promise from promise import Promise