diff --git a/graphene_django/filter/fields.py b/graphene_django/filter/fields.py index a80d8d7..b93977b 100644 --- a/graphene_django/filter/fields.py +++ b/graphene_django/filter/fields.py @@ -61,7 +61,7 @@ class DjangoFilterConnectionField(DjangoConnectionField): low = default_queryset.query.low_mark or queryset.query.low_mark high = default_queryset.query.high_mark or queryset.query.high_mark default_queryset.query.clear_limits() - queryset = default_queryset & queryset + queryset = queryset & default_queryset queryset.query.set_limits(low, high) return queryset diff --git a/graphene_django/filter/tests/test_fields.py b/graphene_django/filter/tests/test_fields.py index 9a0ba21..ef09cfa 100644 --- a/graphene_django/filter/tests/test_fields.py +++ b/graphene_django/filter/tests/test_fields.py @@ -2,7 +2,7 @@ from datetime import datetime import pytest -from graphene import Field, ObjectType, Schema, Argument, Float +from graphene import Field, ObjectType, Schema, Argument, Float, Boolean, String from graphene.relay import Node from graphene_django import DjangoObjectType from graphene_django.forms import (GlobalIDFormField, @@ -10,6 +10,10 @@ from graphene_django.forms import (GlobalIDFormField, from graphene_django.tests.models import Article, Pet, Reporter from graphene_django.utils import DJANGO_FILTER_INSTALLED +# for annotation test +from django.db.models import TextField, Value +from django.db.models.functions import Concat + pytestmark = [] if DJANGO_FILTER_INSTALLED: @@ -534,3 +538,135 @@ def test_should_query_filter_node_double_limit_raises(): assert str(result.errors[0]) == ( 'Received two sliced querysets (high mark) in the connection, please slice only in one.' ) + +def test_order_by_is_perserved(): + class ReporterType(DjangoObjectType): + class Meta: + model = Reporter + interfaces = (Node, ) + filter_fields = () + + class Query(ObjectType): + all_reporters = DjangoFilterConnectionField(ReporterType, reverse_order=Boolean()) + + def resolve_all_reporters(self, info, reverse_order=False, **args): + reporters = Reporter.objects.order_by('first_name') + + if reverse_order: + return reporters.reverse() + + return reporters + + Reporter.objects.create( + first_name='b', + ) + r = Reporter.objects.create( + first_name='a', + ) + + schema = Schema(query=Query) + query = ''' + query NodeFilteringQuery { + allReporters(first: 1) { + edges { + node { + firstName + } + } + } + } + ''' + expected = { + 'allReporters': { + 'edges': [{ + 'node': { + 'firstName': 'a', + } + }] + } + } + + result = schema.execute(query) + assert not result.errors + assert result.data == expected + + + reverse_query = ''' + query NodeFilteringQuery { + allReporters(first: 1, reverseOrder: true) { + edges { + node { + firstName + } + } + } + } + ''' + + reverse_expected = { + 'allReporters': { + 'edges': [{ + 'node': { + 'firstName': 'b', + } + }] + } + } + + reverse_result = schema.execute(reverse_query) + + assert not reverse_result.errors + assert reverse_result.data == reverse_expected + +def test_annotation_is_perserved(): + class ReporterType(DjangoObjectType): + full_name = String() + + def resolve_full_name(instance, info, **args): + return instance.full_name + + class Meta: + model = Reporter + interfaces = (Node, ) + filter_fields = () + + class Query(ObjectType): + all_reporters = DjangoFilterConnectionField(ReporterType) + + def resolve_all_reporters(self, info, **args): + return Reporter.objects.annotate( + full_name=Concat('first_name', Value(' '), 'last_name', output_field=TextField()) + ) + + Reporter.objects.create( + first_name='John', + last_name='Doe', + ) + + schema = Schema(query=Query) + + query = ''' + query NodeFilteringQuery { + allReporters(first: 1) { + edges { + node { + fullName + } + } + } + } + ''' + expected = { + 'allReporters': { + 'edges': [{ + 'node': { + 'fullName': 'John Doe', + } + }] + } + } + + result = schema.execute(query) + + assert not result.errors + assert result.data == expected