diff --git a/graphene_django/fields.py b/graphene_django/fields.py index 78efceb1c..faf470abf 100644 --- a/graphene_django/fields.py +++ b/graphene_django/fields.py @@ -147,21 +147,19 @@ def resolve_connection(cls, connection, args, iterable, max_limit=None): if isinstance(iterable, QuerySet): list_length = iterable.count() - list_slice_length = ( - min(max_limit, list_length) if max_limit is not None else list_length - ) else: 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 # would try to do a negative slicing which makes django throw an # AssertionError 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 connection = connection_from_list_slice( diff --git a/graphene_django/tests/models.py b/graphene_django/tests/models.py index 44a5d8a5c..7f29aa6c8 100644 --- a/graphene_django/tests/models.py +++ b/graphene_django/tests/models.py @@ -67,6 +67,9 @@ def __init__(self, *args, **kwargs): def some_method(self): return 123 + class Meta: + ordering = ("id",) + class CNNReporterManager(models.Manager): def get_queryset(self): diff --git a/graphene_django/tests/test_query.py b/graphene_django/tests/test_query.py index 6add0b863..adfe1de96 100644 --- a/graphene_django/tests/test_query.py +++ b/graphene_django/tests/test_query.py @@ -727,6 +727,58 @@ class Query(graphene.ObjectType): 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(): from promise import Promise