graphql-python / graphql-python/graphene-django
Cannot serialize a CharField with Choices and blank=True
- 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
Assessment
This issue has not been assessed yet.