diff --git a/graphene_django/filter/fields.py b/graphene_django/filter/fields.py index 2ee374c..7d8d2d8 100644 --- a/graphene_django/filter/fields.py +++ b/graphene_django/filter/fields.py @@ -3,6 +3,7 @@ from functools import partial from django.core.exceptions import ValidationError from graphene.types.argument import to_arguments +from graphene.utils.str_converters import to_snake_case from ..fields import DjangoConnectionField from .utils import get_filtering_args_from_filterset, get_filterset_class @@ -61,12 +62,21 @@ class DjangoFilterConnectionField(DjangoConnectionField): def resolve_queryset( cls, connection, iterable, info, args, filtering_args, filterset_class ): + def filter_kwargs(): + kwargs = {} + for k, v in args.items(): + if k in filtering_args: + if k == "order_by": + v = to_snake_case(v) + kwargs[k] = v + return kwargs + qs = super(DjangoFilterConnectionField, cls).resolve_queryset( connection, iterable, info, args ) - filter_kwargs = {k: v for k, v in args.items() if k in filtering_args} + filterset = filterset_class( - data=filter_kwargs, queryset=qs, request=info.context + data=filter_kwargs(), queryset=qs, request=info.context ) if filterset.form.is_valid(): return filterset.qs diff --git a/graphene_django/filter/tests/filters.py b/graphene_django/filter/tests/filters.py index 359d2ba..43b6a87 100644 --- a/graphene_django/filter/tests/filters.py +++ b/graphene_django/filter/tests/filters.py @@ -21,7 +21,7 @@ class ReporterFilter(django_filters.FilterSet): model = Reporter fields = ["first_name", "last_name", "email", "pets"] - order_by = OrderingFilter(fields=("pub_date",)) + order_by = OrderingFilter(fields=("first_name",)) class PetFilter(django_filters.FilterSet): diff --git a/graphene_django/filter/tests/test_fields.py b/graphene_django/filter/tests/test_fields.py index 88749aa..18e7f0c 100644 --- a/graphene_django/filter/tests/test_fields.py +++ b/graphene_django/filter/tests/test_fields.py @@ -713,6 +713,73 @@ def test_should_query_filter_node_limit(): assert result.data == expected +def test_order_by(): + class ReporterType(DjangoObjectType): + class Meta: + model = Reporter + interfaces = (Node,) + + class Query(ObjectType): + all_reporters = DjangoFilterConnectionField( + ReporterType, filterset_class=ReporterFilter + ) + + Reporter.objects.create(first_name="b") + Reporter.objects.create(first_name="a") + + schema = Schema(query=Query) + query = """ + query NodeFilteringQuery { + allReporters(orderBy: "-firstName") { + edges { + node { + firstName + } + } + } + } + """ + expected = { + "allReporters": { + "edges": [{"node": {"firstName": "b"}}, {"node": {"firstName": "a"}}] + } + } + + result = schema.execute(query) + assert not result.errors + assert result.data == expected + + query = """ + query NodeFilteringQuery { + allReporters(orderBy: "-first_name") { + edges { + node { + firstName + } + } + } + } + """ + + result = schema.execute(query) + assert not result.errors + assert result.data == expected + + query = """ + query NodeFilteringQuery { + allReporters(orderBy: "-firtsnaMe") { + edges { + node { + firstName + } + } + } + } + """ + result = schema.execute(query) + assert result.errors + + def test_order_by_is_perserved(): class ReporterType(DjangoObjectType): class Meta: