Skip to content

Commit 2aeb86b

Browse files
tcleonardThomas Leonard
and
Thomas Leonard
authored
fix: backward pagination indexing error when using bigger last argument than total number of elements (#1344)
Co-authored-by: Thomas Leonard <[email protected]>
1 parent 5f1731d commit 2aeb86b

File tree

2 files changed

+88
-11
lines changed

2 files changed

+88
-11
lines changed

graphene_django/fields.py

+13-11
Original file line numberDiff line numberDiff line change
@@ -146,36 +146,38 @@ def resolve_connection(cls, connection, args, iterable, max_limit=None):
146146
iterable = maybe_queryset(iterable)
147147

148148
if isinstance(iterable, QuerySet):
149-
list_length = iterable.count()
149+
array_length = iterable.count()
150150
else:
151-
list_length = len(iterable)
152-
list_slice_length = (
153-
min(max_limit, list_length) if max_limit is not None else list_length
151+
array_length = len(iterable)
152+
array_slice_length = (
153+
min(max_limit, array_length) if max_limit is not None else array_length
154154
)
155155

156156
# If after is higher than list_length, connection_from_list_slice
157157
# would try to do a negative slicing which makes django throw an
158158
# AssertionError
159-
after = min(get_offset_with_default(args.get("after"), -1) + 1, list_length)
159+
slice_start = min(
160+
get_offset_with_default(args.get("after"), -1) + 1, array_length
161+
)
160162

161163
if max_limit is not None and args.get("first", None) is None:
162164
if args.get("last", None) is not None:
163-
after = list_length - args["last"]
165+
slice_start = max(array_length - args["last"], 0)
164166
else:
165167
args["first"] = max_limit
166168

167169
connection = connection_from_array_slice(
168-
iterable[after:],
170+
iterable[slice_start:],
169171
args,
170-
slice_start=after,
171-
array_length=list_length,
172-
array_slice_length=list_slice_length,
172+
slice_start=slice_start,
173+
array_length=array_length,
174+
array_slice_length=array_slice_length,
173175
connection_type=partial(connection_adapter, connection),
174176
edge_type=connection.Edge,
175177
page_info_type=page_info_adapter,
176178
)
177179
connection.iterable = iterable
178-
connection.length = list_length
180+
connection.length = array_length
179181
return connection
180182

181183
@classmethod

graphene_django/tests/test_query.py

+75
Original file line numberDiff line numberDiff line change
@@ -1593,3 +1593,78 @@ class Query(graphene.ObjectType):
15931593
"allReporters": {"edges": [{"node": {"firstName": "Jane", "lastName": "Roe"}},]}
15941594
}
15951595
assert result.data == expected
1596+
1597+
1598+
def test_connection_should_succeed_if_last_higher_than_number_of_objects():
1599+
class ReporterType(DjangoObjectType):
1600+
class Meta:
1601+
model = Reporter
1602+
interfaces = (Node,)
1603+
fields = "__all__"
1604+
1605+
class Query(graphene.ObjectType):
1606+
all_reporters = DjangoConnectionField(ReporterType)
1607+
1608+
schema = graphene.Schema(query=Query)
1609+
query = """
1610+
query ReporterPromiseConnectionQuery ($last: Int) {
1611+
allReporters(last: $last) {
1612+
edges {
1613+
node {
1614+
firstName
1615+
lastName
1616+
}
1617+
}
1618+
}
1619+
}
1620+
"""
1621+
1622+
result = schema.execute(query, variable_values=dict(last=2))
1623+
assert not result.errors
1624+
expected = {"allReporters": {"edges": []}}
1625+
assert result.data == expected
1626+
1627+
Reporter.objects.create(first_name="John", last_name="Doe")
1628+
Reporter.objects.create(first_name="Some", last_name="Guy")
1629+
Reporter.objects.create(first_name="Jane", last_name="Roe")
1630+
Reporter.objects.create(first_name="Some", last_name="Lady")
1631+
1632+
result = schema.execute(query, variable_values=dict(last=2))
1633+
assert not result.errors
1634+
expected = {
1635+
"allReporters": {
1636+
"edges": [
1637+
{"node": {"firstName": "Jane", "lastName": "Roe"}},
1638+
{"node": {"firstName": "Some", "lastName": "Lady"}},
1639+
]
1640+
}
1641+
}
1642+
assert result.data == expected
1643+
1644+
result = schema.execute(query, variable_values=dict(last=4))
1645+
assert not result.errors
1646+
expected = {
1647+
"allReporters": {
1648+
"edges": [
1649+
{"node": {"firstName": "John", "lastName": "Doe"}},
1650+
{"node": {"firstName": "Some", "lastName": "Guy"}},
1651+
{"node": {"firstName": "Jane", "lastName": "Roe"}},
1652+
{"node": {"firstName": "Some", "lastName": "Lady"}},
1653+
]
1654+
}
1655+
}
1656+
assert result.data == expected
1657+
1658+
result = schema.execute(query, variable_values=dict(last=20))
1659+
assert not result.errors
1660+
expected = {
1661+
"allReporters": {
1662+
"edges": [
1663+
{"node": {"firstName": "John", "lastName": "Doe"}},
1664+
{"node": {"firstName": "Some", "lastName": "Guy"}},
1665+
{"node": {"firstName": "Jane", "lastName": "Roe"}},
1666+
{"node": {"firstName": "Some", "lastName": "Lady"}},
1667+
]
1668+
}
1669+
}
1670+
assert result.data == expected

0 commit comments

Comments
 (0)