Skip to content

DjangoFilterConnectionField with resolver returning a list fails #84

Closed
@drakon

Description

@drakon

Didn't run into this in a real project but came up reving the code of another issue (#82).

Basically this test fails:

def test_filter_filterset_related_results_with_resolver():
    class ReporterFilterNode(DjangoObjectType):

        class Meta:
            model = Reporter
            interfaces = (Node, )
            filter_fields = {
                'first_name': ['icontains']
            }

    class Query(ObjectType):
        all_reporters = DjangoFilterConnectionField(ReporterFilterNode)

        def resolve_all_reporters(self, args, context, info):
            return [r1, r3] # For some reason only return some reporters (i.e. authentication)

    r1 = Reporter.objects.create(first_name='A test user', last_name='Last Name', email='test1@test.com')
    r2 = Reporter.objects.create(first_name='Other test user', last_name='Other Last Name', email='test2@test.com')
    r3 = Reporter.objects.create(first_name='Random', last_name='RandomLast', email='random@test.com')

    query = '''
    query {
        allReporters(firstName_Icontains: "test") {
            edges {
                node {
                    id
                }
            }
        }
    }
    '''
    schema = Schema(query=Query)
    result = schema.execute(query)
    assert not result.errors
    # We should only get one reporter
    assert len(result.data['allReporters']['edges']) == 1

It's basically the same as the test 'test_filter_filterset_related_results' but includes a custom resolver that returns a list (a QuerySet probably would work; haven't tested this though).

I'd expect it to return only the one reporter not both (as it was "filtered" out before in the resolver).

The problem comes from here (/graphene_django/fields.py):

    @staticmethod
    def connection_resolver(resolver, connection, default_manager, root, args, context, info):
        iterable = resolver(root, args, context, info)
        if iterable is None:
            iterable = default_manager
        iterable = maybe_queryset(iterable)
        if isinstance(iterable, QuerySet):
            iterable &= maybe_queryset(default_manager)
            _len = iterable.count()
        else:
            _len = iterable.count()
...

Where the default_manager is ignores if the resolver returns a list (instead of a QuerySet). Not sure what a good solution could be here. It's not urgent from my side. Just wanted to report it for completeness.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions