DjangoObjectType interprets string choices fields as required in schema even with blank=True attribute
See original GitHub issueTo reproduce this problem, create a Django model with a choices field with blank=True
:
class MyModel(models.Model):
PERIODIC_INTERVAL_CHOICES = (('Weekly', 'Weekly'),
('Bi-Weekly', 'Bi-Weekly'),
('Monthly', 'Monthly'),
('Quarterly', 'Quarterly'),
('Semi-Annually', 'Semi-Annually'),
'Annually', 'Annually'))
payment_frequency = models.CharField(
blank=True,
choices=PERIODIC_INTERVAL_CHOICES,
max_length=13)
The schema generated by DjangoObjectType will show incorrectly show that this field payment_frequency
is required. This is incorrect – the expected behavior is that it NOT required.
I have been able to fix this issue by patching how the value of required is determined in graphene.converter.convert_django_field_with_choices
(shown for graphene-django 2.0.0) :
def convert_django_field_with_choices(field, registry=None):
# Modified from graphene_django.converter import convert_django_field_with_choices
# to adjust "required"
choices = getattr(field, 'choices', None)
if choices:
meta = field.model._meta
name = to_camel_case('{}_{}'.format(meta.object_name, field.name))
choices = list(get_choices(choices))
named_choices = [(c[0], c[1]) for c in choices]
named_choices_descriptions = {c[0]: c[2] for c in choices}
class EnumWithDescriptionsType(object):
@property
def description(self):
return named_choices_descriptions[self.name]
enum = Enum(name, list(named_choices), type=EnumWithDescriptionsType)
required = not (field.blank or field.null or field.default) # MODIFIED FROM ORIGINAL
return enum(description=field.help_text, required=required)
return convert_django_field(field, registry)
Issue Analytics
- State:
- Created 5 years ago
- Comments:8
Top Results From Across the Web
Queries & ObjectTypes - Graphene-Python
Graphene-Django ships with a special DjangoObjectType that automatically transforms a ... set all fields that should be exposed using the fields attribute.
Read more >Django ForeignKey field ignored by graphene-django when ...
When you look into the debugger you will see that field.related_model is already resolved: Django does this, graphene doesn't even see the ...
Read more >Django + Graphene: From REST to GraphQL - FullStack Labs
The DjangoObjectType by default includes all the fields in the model, but we can explicitly add or exclude any fields we want. The...
Read more >Graphene Documentation - Read the Docs
If you want to expose your data through GraphQL - read the Installation, Schema and Queries section. For more advanced use, check out...
Read more >JSONField Models in Graphene Django - Jerry Ng
The meta field is returned as a JSON string rather than a JSON ... meta field type in your DjangoObjectType to GenericScalar such...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Just want to add a bump to this thread after spending some time dealing with this issue. Django specifies that empty CharFields should be represented as “” rather than None so that there is only one representation of an empty field (“” rather than “” and None). This means setting blank=True and NOT setting null=True on the CharField model definition (https://docs.djangoproject.com/en/2.2/ref/models/fields/#null). Graphene-django v2.4.0 does not handle this case correctly. CharFields with blank=True show as required and will raise an error: "Expected a value of type "{field_from_choices_array}" but received: ", Graphene-django is saying the field is required to be defined and that the “” value is not allowed; however, the “” character is indeed an allowed character for this field in django–in fact it’s the idiomatic character for an empty CharField.
While this thread suggests that explicitly defining the blank field is more idiomatic, django already has a default value for blank CharFields, “”, and using this seems like a sensible default for Graphene-django rather than requiring the “” field to be explicitly defined a la this thread on every CHOICES array that is set on a CharField(blank=True).
Additionally, if I define a “” choice for my CharField(blank=True) as per the suggestions in the links above, graphene-django returns an “A_” value for the blank field–less than ideal.
I’d suggest that and CharField(blank=True) with a choices set should be correctly identified by graphene in the schema as NOT required and to correctly handle a “” value from django by returning a “” value to the GQL client.
I am still having this exact issue even after the #714 . Anyone else experiencing the same problem?