diff --git a/graphene_django/fields.py b/graphene_django/fields.py index f647dbf..f86f997 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -2,7 +2,10 @@ from functools import partial import six from django.db.models.query import QuerySet -from graphql_relay.connection.arrayconnection import connection_from_list_slice +from graphql_relay.connection.arrayconnection import ( + connection_from_list_slice, + get_offset_with_default, +) from promise import Promise from graphene import NonNull @@ -137,6 +140,9 @@ class DjangoConnectionField(ConnectionField): list_length = len(iterable) list_slice_length = max_limit or list_length + after = get_offset_with_default(args.get("after"), -1) + 1 + list_slice_length += after + connection = connection_from_list_slice( iterable, args, diff --git a/graphene_django/tests/test_query.py b/graphene_django/tests/test_query.py index 758b36c..64d720a 100644 --- a/graphene_django/tests/test_query.py +++ b/graphene_django/tests/test_query.py @@ -1130,6 +1130,7 @@ def test_should_have_next_page(graphene_settings): graphene_settings.RELAY_CONNECTION_MAX_LIMIT = 4 reporters = [Reporter(**kwargs) for kwargs in REPORTERS] Reporter.objects.bulk_create(reporters) + db_reporters = Reporter.objects.all() class ReporterType(DjangoObjectType): class Meta: @@ -1144,10 +1145,11 @@ def test_should_have_next_page(graphene_settings): # See `arrayconnection.py::connection_from_list_slice`: # has_next_page=isinstance(first, int) and end_offset < upper_bound query = """ - query AllReporters { - allReporters(first: 4) { + query AllReporters($first: Int, $after: String) { + allReporters(first: $first, after: $after) { pageInfo { hasNextPage + endCursor } edges { node { @@ -1158,11 +1160,26 @@ def test_should_have_next_page(graphene_settings): } """ - result = schema.execute(query) + result = schema.execute(query, variable_values=dict(first=4)) assert not result.errors assert len(result.data["allReporters"]["edges"]) == 4 assert result.data["allReporters"]["pageInfo"]["hasNextPage"] + last_result = result.data["allReporters"]["pageInfo"]["endCursor"] + result2 = schema.execute(query, variable_values=dict(first=4, after=last_result)) + assert not result2.errors + assert len(result2.data["allReporters"]["edges"]) == 2 + assert not result2.data["allReporters"]["pageInfo"]["hasNextPage"] + gql_reporters = result.data["allReporters"]["edges"] + result2.data["allReporters"]["edges"] + + assert { + to_global_id("ReporterType", reporter.id) + for reporter in db_reporters + } == { + gql_reporter["node"]["id"] + for gql_reporter in gql_reporters + } + def test_should_preserve_prefetch_related(django_assert_num_queries): class ReporterType(DjangoObjectType):