mirror of
https://github.com/graphql-python/graphene-django.git
synced 2024-11-25 19:14:11 +03:00
Add BlankField and mount enums using it v3 (#1096)
* Add BlankField and mount enums using it * fix lint error from duplicate import Co-authored-by: Jonathan Kim <jkimbo@gmail.com>
This commit is contained in:
parent
10e48c27b7
commit
bcc7f85dad
|
@ -1,10 +1,11 @@
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from functools import singledispatch
|
from functools import singledispatch, partial, wraps
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
from django.utils.functional import Promise
|
from django.utils.functional import Promise
|
||||||
from django.utils.module_loading import import_string
|
from django.utils.module_loading import import_string
|
||||||
|
|
||||||
from graphene import (
|
from graphene import (
|
||||||
ID,
|
ID,
|
||||||
UUID,
|
UUID,
|
||||||
|
@ -22,6 +23,7 @@ from graphene import (
|
||||||
Time,
|
Time,
|
||||||
Decimal,
|
Decimal,
|
||||||
)
|
)
|
||||||
|
from graphene.types.resolver import get_default_resolver
|
||||||
from graphene.types.json import JSONString
|
from graphene.types.json import JSONString
|
||||||
from graphene.utils.str_converters import to_camel_case
|
from graphene.utils.str_converters import to_camel_case
|
||||||
from graphql import GraphQLError, assert_valid_name
|
from graphql import GraphQLError, assert_valid_name
|
||||||
|
@ -33,6 +35,24 @@ from .settings import graphene_settings
|
||||||
from .utils.str_converters import to_const
|
from .utils.str_converters import to_const
|
||||||
|
|
||||||
|
|
||||||
|
class BlankValueField(Field):
|
||||||
|
def get_resolver(self, parent_resolver):
|
||||||
|
resolver = self.resolver or parent_resolver
|
||||||
|
|
||||||
|
# create custom resolver
|
||||||
|
def blank_field_wrapper(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapped_resolver(*args, **kwargs):
|
||||||
|
return_value = func(*args, **kwargs)
|
||||||
|
if return_value == "":
|
||||||
|
return None
|
||||||
|
return return_value
|
||||||
|
|
||||||
|
return wrapped_resolver
|
||||||
|
|
||||||
|
return blank_field_wrapper(resolver)
|
||||||
|
|
||||||
|
|
||||||
def convert_choice_name(name):
|
def convert_choice_name(name):
|
||||||
name = to_const(force_str(name))
|
name = to_const(force_str(name))
|
||||||
try:
|
try:
|
||||||
|
@ -71,7 +91,8 @@ def convert_choices_to_named_enum_with_descriptions(name, choices):
|
||||||
def description(self):
|
def description(self):
|
||||||
return str(named_choices_descriptions[self.name])
|
return str(named_choices_descriptions[self.name])
|
||||||
|
|
||||||
return Enum(name, list(named_choices), type=EnumWithDescriptionsType)
|
return_type = Enum(name, list(named_choices), type=EnumWithDescriptionsType)
|
||||||
|
return return_type
|
||||||
|
|
||||||
|
|
||||||
def generate_enum_name(django_model_meta, field):
|
def generate_enum_name(django_model_meta, field):
|
||||||
|
@ -108,11 +129,12 @@ def convert_django_field_with_choices(
|
||||||
return converted
|
return converted
|
||||||
choices = getattr(field, "choices", None)
|
choices = getattr(field, "choices", None)
|
||||||
if choices and convert_choices_to_enum:
|
if choices and convert_choices_to_enum:
|
||||||
enum = convert_choice_field_to_enum(field)
|
EnumCls = convert_choice_field_to_enum(field)
|
||||||
required = not (field.blank or field.null)
|
required = not (field.blank or field.null)
|
||||||
converted = enum(
|
|
||||||
|
converted = EnumCls(
|
||||||
description=get_django_field_description(field), required=required
|
description=get_django_field_description(field), required=required
|
||||||
)
|
).mount_as(BlankValueField)
|
||||||
else:
|
else:
|
||||||
converted = convert_django_field(field, registry)
|
converted = convert_django_field(field, registry)
|
||||||
if registry is not None:
|
if registry is not None:
|
||||||
|
|
|
@ -164,8 +164,7 @@ def test_field_with_choices_convert_enum():
|
||||||
class Meta:
|
class Meta:
|
||||||
app_label = "test"
|
app_label = "test"
|
||||||
|
|
||||||
graphene_type = convert_django_field_with_choices(field)
|
graphene_type = convert_django_field_with_choices(field).type.of_type
|
||||||
assert isinstance(graphene_type, graphene.Enum)
|
|
||||||
assert graphene_type._meta.name == "TestTranslatedModelLanguageChoices"
|
assert graphene_type._meta.name == "TestTranslatedModelLanguageChoices"
|
||||||
assert graphene_type._meta.enum.__members__["ES"].value == "es"
|
assert graphene_type._meta.enum.__members__["ES"].value == "es"
|
||||||
assert graphene_type._meta.enum.__members__["ES"].description == "Spanish"
|
assert graphene_type._meta.enum.__members__["ES"].description == "Spanish"
|
||||||
|
@ -418,3 +417,43 @@ def test_generate_v2_enum_name(graphene_settings):
|
||||||
app_label="some_long_app_name", object_name="SomeObject"
|
app_label="some_long_app_name", object_name="SomeObject"
|
||||||
)
|
)
|
||||||
assert generate_enum_name(model_meta, field) == "SomeObjectFizzBuzz"
|
assert generate_enum_name(model_meta, field) == "SomeObjectFizzBuzz"
|
||||||
|
|
||||||
|
|
||||||
|
def test_choice_enum_blank_value():
|
||||||
|
"""Test that choice fields with blank values work"""
|
||||||
|
|
||||||
|
class ReporterType(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = Reporter
|
||||||
|
fields = (
|
||||||
|
"first_name",
|
||||||
|
"a_choice",
|
||||||
|
)
|
||||||
|
|
||||||
|
class Query(graphene.ObjectType):
|
||||||
|
reporter = graphene.Field(ReporterType)
|
||||||
|
|
||||||
|
def resolve_reporter(root, info):
|
||||||
|
return Reporter.objects.first()
|
||||||
|
|
||||||
|
schema = graphene.Schema(query=Query)
|
||||||
|
|
||||||
|
# Create model with empty choice option
|
||||||
|
Reporter.objects.create(
|
||||||
|
first_name="Bridget", last_name="Jones", email="bridget@example.com"
|
||||||
|
)
|
||||||
|
|
||||||
|
result = schema.execute(
|
||||||
|
"""
|
||||||
|
query {
|
||||||
|
reporter {
|
||||||
|
firstName
|
||||||
|
aChoice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
assert not result.errors
|
||||||
|
assert result.data == {
|
||||||
|
"reporter": {"firstName": "Bridget", "aChoice": None},
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user