mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-08 23:50:38 +03:00
Handle complex input types
This commit is contained in:
parent
b5abccb1dc
commit
9c27db7ed5
|
@ -1,11 +1,14 @@
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from .base import BaseOptions, BaseType
|
from .base import BaseOptions, BaseType
|
||||||
|
from .field import Field
|
||||||
from .inputfield import InputField
|
from .inputfield import InputField
|
||||||
|
from .objecttype import ObjectType
|
||||||
|
from .scalars import Scalar
|
||||||
|
from .structures import List, NonNull
|
||||||
from .unmountedtype import UnmountedType
|
from .unmountedtype import UnmountedType
|
||||||
from .utils import yank_fields_from_attrs
|
from .utils import yank_fields_from_attrs
|
||||||
|
|
||||||
|
|
||||||
# For static type checking with Mypy
|
# For static type checking with Mypy
|
||||||
MYPY = False
|
MYPY = False
|
||||||
if MYPY:
|
if MYPY:
|
||||||
|
@ -24,11 +27,29 @@ class InputObjectTypeContainer(dict, BaseType):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
dict.__init__(self, *args, **kwargs)
|
dict.__init__(self, *args, **kwargs)
|
||||||
for key in self._meta.fields.keys():
|
for key in self._meta.fields.keys():
|
||||||
setattr(self, key, self.get(key, None))
|
field = getattr(self, key, None)
|
||||||
|
if field is None or self.get(key, None) is None:
|
||||||
|
value = None
|
||||||
|
else:
|
||||||
|
value = InputObjectTypeContainer._get_typed_field_value(field, self[key])
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
def __init_subclass__(cls, *args, **kwargs):
|
def __init_subclass__(cls, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_typed_field_value(field_or_type, value):
|
||||||
|
if isinstance(field_or_type, NonNull):
|
||||||
|
return InputObjectTypeContainer._get_typed_field_value(field_or_type.of_type, value)
|
||||||
|
elif isinstance(field_or_type, List):
|
||||||
|
return [
|
||||||
|
InputObjectTypeContainer._get_typed_field_value(field_or_type.of_type, v)
|
||||||
|
for v in value
|
||||||
|
]
|
||||||
|
elif hasattr(field_or_type, '_meta') and hasattr(field_or_type._meta, 'container'):
|
||||||
|
return field_or_type._meta.container(value)
|
||||||
|
else:
|
||||||
|
return value
|
||||||
|
|
||||||
class InputObjectType(UnmountedType, BaseType):
|
class InputObjectType(UnmountedType, BaseType):
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -4,6 +4,7 @@ from graphql.type import (GraphQLArgument, GraphQLEnumType, GraphQLEnumValue,
|
||||||
GraphQLInputObjectType, GraphQLInterfaceType,
|
GraphQLInputObjectType, GraphQLInterfaceType,
|
||||||
GraphQLObjectType, GraphQLString)
|
GraphQLObjectType, GraphQLString)
|
||||||
|
|
||||||
|
from ..structures import List, NonNull
|
||||||
from ..dynamic import Dynamic
|
from ..dynamic import Dynamic
|
||||||
from ..enum import Enum
|
from ..enum import Enum
|
||||||
from ..field import Field
|
from ..field import Field
|
||||||
|
@ -11,7 +12,7 @@ from ..inputfield import InputField
|
||||||
from ..inputobjecttype import InputObjectType
|
from ..inputobjecttype import InputObjectType
|
||||||
from ..interface import Interface
|
from ..interface import Interface
|
||||||
from ..objecttype import ObjectType
|
from ..objecttype import ObjectType
|
||||||
from ..scalars import String
|
from ..scalars import String, Int
|
||||||
from ..typemap import TypeMap
|
from ..typemap import TypeMap
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,10 +120,18 @@ def test_interface():
|
||||||
|
|
||||||
|
|
||||||
def test_inputobject():
|
def test_inputobject():
|
||||||
|
class OtherObjectType(InputObjectType):
|
||||||
|
thingy = NonNull(Int)
|
||||||
|
|
||||||
|
class MyInnerObjectType(InputObjectType):
|
||||||
|
some_field = String()
|
||||||
|
some_other_field = List(OtherObjectType)
|
||||||
|
|
||||||
class MyInputObjectType(InputObjectType):
|
class MyInputObjectType(InputObjectType):
|
||||||
'''Description'''
|
'''Description'''
|
||||||
foo_bar = String(description='Field description')
|
foo_bar = String(description='Field description')
|
||||||
bar = String(name='gizmo')
|
bar = String(name='gizmo')
|
||||||
|
baz = NonNull(MyInnerObjectType)
|
||||||
own = InputField(lambda: MyInputObjectType)
|
own = InputField(lambda: MyInputObjectType)
|
||||||
|
|
||||||
def resolve_foo_bar(self, args, info):
|
def resolve_foo_bar(self, args, info):
|
||||||
|
@ -136,14 +145,23 @@ def test_inputobject():
|
||||||
assert graphql_type.description == 'Description'
|
assert graphql_type.description == 'Description'
|
||||||
|
|
||||||
# Container
|
# Container
|
||||||
container = graphql_type.create_container({'bar': 'oh!'})
|
container = graphql_type.create_container({
|
||||||
|
'bar': 'oh!',
|
||||||
|
'baz': {
|
||||||
|
'some_other_field': [{'thingy': 1}, {'thingy': 2}]
|
||||||
|
}
|
||||||
|
})
|
||||||
assert isinstance(container, MyInputObjectType)
|
assert isinstance(container, MyInputObjectType)
|
||||||
assert 'bar' in container
|
assert 'bar' in container
|
||||||
assert container.bar == 'oh!'
|
assert container.bar == 'oh!'
|
||||||
assert 'foo_bar' not in container
|
assert 'foo_bar' not in container
|
||||||
|
assert container.foo_bar is None
|
||||||
|
assert container.baz.some_field is None
|
||||||
|
assert container.baz.some_other_field[0].thingy == 1
|
||||||
|
assert container.baz.some_other_field[1].thingy == 2
|
||||||
|
|
||||||
fields = graphql_type.fields
|
fields = graphql_type.fields
|
||||||
assert list(fields.keys()) == ['fooBar', 'gizmo', 'own']
|
assert list(fields.keys()) == ['fooBar', 'gizmo', 'baz', 'own']
|
||||||
own_field = fields['own']
|
own_field = fields['own']
|
||||||
assert own_field.type == graphql_type
|
assert own_field.type == graphql_type
|
||||||
foo_field = fields['fooBar']
|
foo_field = fields['fooBar']
|
||||||
|
|
Loading…
Reference in New Issue
Block a user