fields.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. from functools import partial
  2. import graphene
  3. from graphene_django import DjangoListField
  4. from .utils import get_graphene_type
  5. __all__ = (
  6. 'ObjectField',
  7. 'ObjectListField',
  8. )
  9. class ObjectField(graphene.Field):
  10. """
  11. Retrieve a single object, identified by its numeric ID.
  12. """
  13. def __init__(self, *args, **kwargs):
  14. if 'id' not in kwargs:
  15. kwargs['id'] = graphene.Int(required=True)
  16. super().__init__(*args, **kwargs)
  17. @staticmethod
  18. def object_resolver(django_object_type, root, info, **args):
  19. """
  20. Return an object given its numeric ID.
  21. """
  22. manager = django_object_type._meta.model._default_manager
  23. queryset = django_object_type.get_queryset(manager, info)
  24. return queryset.get(**args)
  25. def get_resolver(self, parent_resolver):
  26. return partial(self.object_resolver, self._type)
  27. class ObjectListField(DjangoListField):
  28. """
  29. Retrieve a list of objects, optionally filtered by one or more FilterSet filters.
  30. """
  31. def __init__(self, _type, *args, **kwargs):
  32. filter_kwargs = {}
  33. # Get FilterSet kwargs
  34. filterset_class = getattr(_type._meta, 'filterset_class', None)
  35. if filterset_class:
  36. for filter_name, filter_field in filterset_class.get_filters().items():
  37. field_type = get_graphene_type(type(filter_field))
  38. filter_kwargs[filter_name] = graphene.Argument(field_type)
  39. super().__init__(_type, args=filter_kwargs, *args, **kwargs)
  40. @staticmethod
  41. def list_resolver(django_object_type, resolver, default_manager, root, info, **args):
  42. queryset = super(ObjectListField, ObjectListField).list_resolver(django_object_type, resolver, default_manager, root, info, **args)
  43. # Instantiate and apply the FilterSet, if defined
  44. filterset_class = django_object_type._meta.filterset_class
  45. if filterset_class:
  46. filterset = filterset_class(data=args, queryset=queryset, request=info.context)
  47. if not filterset.is_valid():
  48. return queryset.none()
  49. return filterset.qs
  50. return queryset