Skip to content

Cannot serialize a CharField with Choices and blank=True #1005

Open
@cansin

Description

@cansin
  • What is the current behavior?

Trying to return a value of a field such as models.CharField(choices=some_choices, blank=True, max_length=64) with a blank value from Graphene causes a graphql.error.base.GraphQLError: Expected a value of type "SomeChoice" but received:

Reproduction is at https://repl.it/repls/WaryRespectfulTrace#README.md

Given a model such as:

from django.db import models
from model_utils.models import UUIDModel
from django.utils.translation import gettext_lazy as _

class Person(UUIDModel, models.Model):
    class Gender(models.TextChoices):
        MALE = "male", _("Male")
        FEMALE = "female", _("Female")
        OTHER = "other", _("Other")

    gender = models.CharField(choices=Gender.choices, blank=True, max_length=64)

and a type such as:

from graphene_django import DjangoObjectType

class PersonType(DjangoObjectType):
    class Meta:
        model = Person
        use_connection = True

and a query such as:

import graphene

class Query(graphene.ObjectType):
    person = graphene.Field(PersonType, id=graphene.UUID())

    @classmethod
    def resolve_person(cls, root, info, id):
        return Person.objects.get(id=id)

Running a GraphQL such as:

query {
    person(id: "some-uuid") {
        id
        gender
    }
}

results in a graphql.error.base.GraphQLError: Expected a value of type "PersonGender" but received: iff the person's gender value is blank.

The stacktrace is:

Traceback (most recent call last):
  File "/Users/user/.virtualenvs/code/lib/python3.7/site-packages/promise/promise.py", line 87, in try_catch
    return (handler(*args, **kwargs), None)
  File "/Users/user/.virtualenvs/code/lib/python3.7/site-packages/graphql/execution/executor.py", line 532, in <lambda>
    exe_context, return_type, field_asts, info, path, resolved
  File "/Users/user/.virtualenvs/code/lib/python3.7/site-packages/graphql/execution/executor.py", line 563, in complete_value
    return complete_leaf_value(return_type, path, result)
  File "/Users/user/.virtualenvs/code/lib/python3.7/site-packages/graphql/execution/executor.py", line 633, in complete_leaf_value
    path=path,
graphql.error.base.GraphQLError: Expected a value of type "PersonGender" but received: 
  • What is the expected behavior?

The empty value should be successfully returned.

  • What is the motivation / use case for changing the behavior?

Left unfixed, the clients are receiving an erroneous error (pun intended 😛). This is especially problematic when we are trying to distinguish between an error state vs a valid state.

  • Please tell us about your environment:

    • Version:
Django==3.0.7
django-cors-headers==3.2.1
django-environ==0.4.5
django-extensions==2.2.9
django-filter==2.2.0
django-graphql-jwt==0.3.1
django-heroku==0.3.1
django-model-utils==4.0.0
django-polymorphic==2.1.2
django-redis-cache==2.1.0
django-rq==2.3.0
django-sendgrid-v5==0.8.1
graphene==2.1.8
graphene-django==2.10.1
graphene-stubs==0.15
graphql-core==2.3.2
graphql-relay==2.0.1
  • Platform:
Python 3.7.3
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow)

I realize a similar issue was previously reported at #503 and #714 and fixed at #714 .

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions