Fix pagination using 'after'

This commit is contained in:
Paul Craciunoiu 2020-06-09 12:35:14 -06:00
parent 6bc0f6d9d6
commit 1cb7fc63bf
2 changed files with 27 additions and 4 deletions

View File

@ -2,7 +2,10 @@ from functools import partial
import six import six
from django.db.models.query import QuerySet 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 promise import Promise
from graphene import NonNull from graphene import NonNull
@ -137,6 +140,9 @@ class DjangoConnectionField(ConnectionField):
list_length = len(iterable) list_length = len(iterable)
list_slice_length = max_limit or list_length 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( connection = connection_from_list_slice(
iterable, iterable,
args, args,

View File

@ -1130,6 +1130,7 @@ def test_should_have_next_page(graphene_settings):
graphene_settings.RELAY_CONNECTION_MAX_LIMIT = 4 graphene_settings.RELAY_CONNECTION_MAX_LIMIT = 4
reporters = [Reporter(**kwargs) for kwargs in REPORTERS] reporters = [Reporter(**kwargs) for kwargs in REPORTERS]
Reporter.objects.bulk_create(reporters) Reporter.objects.bulk_create(reporters)
db_reporters = Reporter.objects.all()
class ReporterType(DjangoObjectType): class ReporterType(DjangoObjectType):
class Meta: class Meta:
@ -1144,10 +1145,11 @@ def test_should_have_next_page(graphene_settings):
# See `arrayconnection.py::connection_from_list_slice`: # See `arrayconnection.py::connection_from_list_slice`:
# has_next_page=isinstance(first, int) and end_offset < upper_bound # has_next_page=isinstance(first, int) and end_offset < upper_bound
query = """ query = """
query AllReporters { query AllReporters($first: Int, $after: String) {
allReporters(first: 4) { allReporters(first: $first, after: $after) {
pageInfo { pageInfo {
hasNextPage hasNextPage
endCursor
} }
edges { edges {
node { 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 not result.errors
assert len(result.data["allReporters"]["edges"]) == 4 assert len(result.data["allReporters"]["edges"]) == 4
assert result.data["allReporters"]["pageInfo"]["hasNextPage"] 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): def test_should_preserve_prefetch_related(django_assert_num_queries):
class ReporterType(DjangoObjectType): class ReporterType(DjangoObjectType):