Description
I'm new to graphene-django so please bear with me if my issue is nonsensical.
I've been spending some time trying to figure out why, when using a resolution method in combination with a DjangoFilterConnectionField
any prefetches are being unused. I've traced it down to a few things.
Within DjangoFilterConnectionField.merge_querysets
an &
operator is used to merge two Django QuerySet
s. The __and__
method on QuerySet
creates a new instance of its class, thereby losing any internal caching that may have been accomplished when using prefetch_related()
. There doesn't seem to be much of a way around this without accessing private attributes of the QuerySet
object, which is clearly bad practice.
I then noticed that DjangoConnectionField.resolve_connection
checks to see if iterable is not default_manager
. If it's not (which as far as I can tell it never will be if you have a resolve_things
method on your Query class) it will then follow down the aforementioned path which winds up wiping cache because it creates a new QuerySet
.
I wonder, what is the purpose of the following code in resolve_connection
? If I disable it, the queryset my resolve_things method returns is actually used and thus the prefetch works.
if iterable is not default_manager:
default_queryset = maybe_queryset(default_manager)
iterable = cls.merge_querysets(default_queryset, iterable)
For reference, my implementation is as follows:
class PostType(DjangoObjectType):
class Meta:
model = Post
filter_fields = ['id', 'title']
interfaces = (graphene.relay.Node, )
class Query(graphene.ObjectType):
posts = DjangoFilterConnectionField(PostType)
def resolve_posts(self, info, **kwargs):
return Post.objects.prefetch_related('customer_posts').all()