Unable to return Null/None in a custom Scalar type
McPo opened this issue · comments
Attempting to return None if the image is a blank string
class Image(graphene.types.Scalar):
@staticmethod
def serialize(image):
return image.url if image else None
@staticmethod
def parse_literal(node):
return None
@staticmethod
def parse_value(value):
return None
but am receiving the following error
graphql.error.base.GraphQLError: Expected a value of type "Image" but received:
Going by the comment at https://github.com/graphql-python/graphql-core/blob/master/graphql/execution/executor.py#L615 this should be possible, however the code does not imply that its possible.
There appears to be PRs for this feature (By adding an explicit NullValue)
graphql-python/graphql-core#119
graphql-python/graphql-core#172
But it appears this issue isn't gonna be fixed until graphql-core-next is released. Ive attempted to install the next alpha version along with graphene-django but it seems unhappy. (Are they currently incompatible)?
Ended up having to monkey patch it
# Allow None to be returned in type serialiser
from graphql.execution import executor
def patched_complete_leaf_value(return_type, path, result):
assert hasattr(return_type, "serialize"), "Missing serialize method on type"
serialized_result = return_type.serialize(result)
return serialized_result
executor.complete_leaf_value = patched_complete_leaf_value
Also regarding graphene-django and django-core v3. I just saw this post graphql-python/graphene-django#705
Looks like it will be coming in the near future.
Another way to do it is in the resolver thats passed to the field. No monkey patch required.
from graphene.utils.str_converters import to_snake_case
def ResolveNoneIfEmpty(instance, info):
field_name = to_snake_case(info.field_name)
field_value = getattr(instance, field_name)
return field_value if field_value else None
NullEmptyString = lambda *args, **kwargs : graphene.String(*args, **kwargs, resolver=ResolveNoneIfEmpty)
class Member(DjangoObjectType):
....
display_name = NullEmptyString()