graphene-django-extras
graphene-django-extras copied to clipboard
Custom Resolver for DjangoFilterPaginateListField/DjangoFilterListField/DjangoListObjectField
Just wondering if it is possible to define custom resolver for the fields exposed by graphene-django-extras.
My project has two Apps (with separate databases) but with relationships across apps.
I would like to use a custom resolver to select related objects where the connection is not defined in the ORM but still have access to pagination and filtering.
I tried to do this as I would in Graphene-Django but the resolver function isn't called when used with any of the fields provided by this library. I tried it with graphene.field and the resolver function is run.
class SiteObjectType(DjangoObjectType):
class Meta:
description = "Site model type definition "
model = models.Site
vehicles = DjangoListObjectField(types.Vehicle)
def resolve_vehicles(self, info, **kwargs):
# something like this to select the relevant vehicle objects
related_vehicles = Vehicles.object.filter(id__in="self.id")
return related_vehicles
Is this expected behaviour and is there any way around it?
Thanks for the great work on this extension!
I'm having the same issue, trying to filter on a search parameter to then receive paginated results, but as the resolver is skipped - as is my search!
Hi @webel and @louisdvs, thanks for ask and sorry for delay. Right now, in my free time, I'm working on a new version of graphene-django-extras with many new features implemented and most of the issues reported corrected (including this).
Thanks for the response @eamigo86.
As a temp solution, I've used DjangoFilterPaginateListField for all of my paginated fields. It just means that I have had to add a custom field for TotalCount that is resolved on every child element (not great) but will get me started.
Type:
class SiteType(DjangoObjectType):
total_count = graphene.Int()
def resolve_total_count(self, info):
count = models.Site.objects.count()
return count
class Meta:
description = "Site model type definition "
model = models.Site
filter_fields = {
'id': ['exact', ],
'name': ['exact', ],
'description': ['icontains', ],
}
Query:
site = DjangoObjectField(
types.SiteType,
description="")
all_sites = DjangoFilterPaginateListField(
types.SiteType,
pagination=LimitOffsetGraphqlPagination(default_limit=25),
description='paginated list of sites')
Do you plan to implement this someday? Or, if you have an implementation example, I will implement it.
I ran into the same issue and I solved it by subclassing the field like so
from graphene_django_extras import DjangoFilterListField
from functools import partial
from graphene.types.structures import Structure
class CustomDjangoFilterListField(DjangoFilterListField):
def __init__(
self,
_type,
fields=None,
extra_filter_meta=None,
filterset_class=None,
*args,
**kwargs,
):
super().__init__(
_type,
fields=None,
extra_filter_meta=None,
filterset_class=None,
*args,
**kwargs,
)
@staticmethod
def list_resolver(
manager, filterset_class, filtering_args, constraint_func, root, info, **kwargs
):
queryset = DjangoFilterListField.list_resolver(
manager, filterset_class, filtering_args, root, info, **kwargs
)
if constraint_func:
return constraint_func(queryset, info)
else:
return queryset
def get_resolver(self, parent_resolver):
current_type = self.type
while isinstance(current_type, Structure):
current_type = current_type.of_type
try:
constraint_func = None
constraint_func = current_type.constraint_func
except Exception:
pass
return partial(
self.list_resolver,
current_type._meta.model._default_manager,
self.filterset_class,
self.filtering_args,
constraint_func,
)
So if you want to use it in a model, you can do so like:
class CodeQuestionTestCaseType(DjangoObjectType):
class Meta:
model = CodeQuestionTestCase
filter_fields = {"input": ("iexact",), "output": ("iexact",)}
@classmethod
def constraint_func(self,queryset,info):
if info.context.user.user_type == "STUDENT":
return None
return queryset
I don't really know if it's the best method but this let me do a lot of checks before returning data to the user
Any News ?
Hi @webel and @louisdvs, thanks for ask and sorry for delay. Right now, in my free time, I'm working on a new version of graphene-django-extras with many new features implemented and most of the issues reported corrected (including this).
@eamigo86 You said this nearly 3 years ago, have you been able to make much progress. Would love to get updates on this! Thanks!