graphql-python / graphql-python/graphene-django

Cannot serialize a CharField with Choices and blank=True

Open
#1,005 5 comments 5 reactions 1 assignee Claimed by @jkimbo View on GitHub
🐛bug
Dominant language
Python
Stars
4.4k
Forks
760
PR merge metrics
No merged PRs in 30d

Description

* **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:

```py
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:

```py
from graphene_django import DjangoObjectType

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

and a query such as:

```py
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:

```gql
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
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 https://github.com/graphql-python/graphene-django/issues/503 and https://github.com/graphql-python/graphene-django/pull/714 and fixed at https://github.com/graphql-python/graphene-django/pull/714 .

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.