mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-29 04:53:55 +03:00
Improved TypeMap and Dynamic Field to optionally include the schema
This commit is contained in:
parent
ecb1edd5c2
commit
2f87698a0b
|
@ -9,10 +9,13 @@ class Dynamic(MountedType):
|
|||
the schema. So we can have lazy fields.
|
||||
'''
|
||||
|
||||
def __init__(self, type, _creation_counter=None):
|
||||
def __init__(self, type, with_schema=False, _creation_counter=None):
|
||||
super(Dynamic, self).__init__(_creation_counter=_creation_counter)
|
||||
assert inspect.isfunction(type)
|
||||
self.type = type
|
||||
self.with_schema = with_schema
|
||||
|
||||
def get_type(self):
|
||||
def get_type(self, schema=None):
|
||||
if schema and self.with_schema:
|
||||
return self.type(schema=schema)
|
||||
return self.type()
|
||||
|
|
|
@ -94,4 +94,4 @@ class Schema(GraphQLSchema):
|
|||
]
|
||||
if self.types:
|
||||
initial_types += self.types
|
||||
self._type_map = TypeMap(initial_types, auto_camelcase=self.auto_camelcase)
|
||||
self._type_map = TypeMap(initial_types, auto_camelcase=self.auto_camelcase, schema=self)
|
||||
|
|
|
@ -51,8 +51,9 @@ def resolve_type(resolve_type_func, map, type_name, root, context, info):
|
|||
|
||||
class TypeMap(GraphQLTypeMap):
|
||||
|
||||
def __init__(self, types, auto_camelcase=True):
|
||||
def __init__(self, types, auto_camelcase=True, schema=None):
|
||||
self.auto_camelcase = auto_camelcase
|
||||
self.schema = schema
|
||||
super(TypeMap, self).__init__(types)
|
||||
|
||||
def reducer(self, map, type):
|
||||
|
@ -72,21 +73,25 @@ class TypeMap(GraphQLTypeMap):
|
|||
if isinstance(_type, GrapheneGraphQLType):
|
||||
assert _type.graphene_type == type
|
||||
return map
|
||||
|
||||
if issubclass(type, ObjectType):
|
||||
return self.construct_objecttype(map, type)
|
||||
internal_type = self.construct_objecttype(map, type)
|
||||
if issubclass(type, InputObjectType):
|
||||
return self.construct_inputobjecttype(map, type)
|
||||
internal_type = self.construct_inputobjecttype(map, type)
|
||||
if issubclass(type, Interface):
|
||||
return self.construct_interface(map, type)
|
||||
internal_type = self.construct_interface(map, type)
|
||||
if issubclass(type, Scalar):
|
||||
return self.construct_scalar(map, type)
|
||||
internal_type = self.construct_scalar(map, type)
|
||||
if issubclass(type, Enum):
|
||||
return self.construct_enum(map, type)
|
||||
internal_type = self.construct_enum(map, type)
|
||||
if issubclass(type, Union):
|
||||
return self.construct_union(map, type)
|
||||
return map
|
||||
internal_type = self.construct_union(map, type)
|
||||
|
||||
return GraphQLTypeMap.reducer(map, internal_type)
|
||||
|
||||
def construct_scalar(self, map, type):
|
||||
# We have a mapping to the original GraphQL types
|
||||
# so there are no collisions.
|
||||
_scalars = {
|
||||
String: GraphQLString,
|
||||
Int: GraphQLInt,
|
||||
|
@ -95,18 +100,17 @@ class TypeMap(GraphQLTypeMap):
|
|||
ID: GraphQLID
|
||||
}
|
||||
if type in _scalars:
|
||||
map[type._meta.name] = _scalars[type]
|
||||
else:
|
||||
map[type._meta.name] = GrapheneScalarType(
|
||||
graphene_type=type,
|
||||
name=type._meta.name,
|
||||
description=type._meta.description,
|
||||
return _scalars[type]
|
||||
|
||||
serialize=getattr(type, 'serialize', None),
|
||||
parse_value=getattr(type, 'parse_value', None),
|
||||
parse_literal=getattr(type, 'parse_literal', None),
|
||||
)
|
||||
return map
|
||||
return GrapheneScalarType(
|
||||
graphene_type=type,
|
||||
name=type._meta.name,
|
||||
description=type._meta.description,
|
||||
|
||||
serialize=getattr(type, 'serialize', None),
|
||||
parse_value=getattr(type, 'parse_value', None),
|
||||
parse_literal=getattr(type, 'parse_literal', None),
|
||||
)
|
||||
|
||||
def construct_enum(self, map, type):
|
||||
values = OrderedDict()
|
||||
|
@ -117,61 +121,61 @@ class TypeMap(GraphQLTypeMap):
|
|||
description=getattr(value, 'description', None),
|
||||
deprecation_reason=getattr(value, 'deprecation_reason', None)
|
||||
)
|
||||
map[type._meta.name] = GrapheneEnumType(
|
||||
return GrapheneEnumType(
|
||||
graphene_type=type,
|
||||
values=values,
|
||||
name=type._meta.name,
|
||||
description=type._meta.description,
|
||||
)
|
||||
return map
|
||||
|
||||
def construct_objecttype(self, map, type):
|
||||
if type._meta.name in map:
|
||||
_type = map[type._meta.name]
|
||||
if isinstance(_type, GrapheneGraphQLType):
|
||||
assert _type.graphene_type == type
|
||||
return map
|
||||
map[type._meta.name] = GrapheneObjectType(
|
||||
return _type
|
||||
|
||||
def interfaces():
|
||||
interfaces = []
|
||||
for interface in type._meta.interfaces:
|
||||
i = self.construct_interface(map, interface)
|
||||
interfaces.append(i)
|
||||
return interfaces
|
||||
|
||||
return GrapheneObjectType(
|
||||
graphene_type=type,
|
||||
name=type._meta.name,
|
||||
description=type._meta.description,
|
||||
fields=None,
|
||||
fields=partial(self.construct_fields_for_type, map, type),
|
||||
is_type_of=type.is_type_of,
|
||||
interfaces=None
|
||||
interfaces=interfaces
|
||||
)
|
||||
interfaces = []
|
||||
for i in type._meta.interfaces:
|
||||
map = self.reducer(map, i)
|
||||
interfaces.append(map[i._meta.name])
|
||||
map[type._meta.name]._provided_interfaces = interfaces
|
||||
map[type._meta.name]._fields = self.construct_fields_for_type(map, type)
|
||||
# self.reducer(map, map[type._meta.name])
|
||||
return map
|
||||
|
||||
def construct_interface(self, map, type):
|
||||
if type._meta.name in map:
|
||||
_type = map[type._meta.name]
|
||||
if isinstance(_type, GrapheneInterfaceType):
|
||||
assert _type.graphene_type == type
|
||||
return _type
|
||||
|
||||
_resolve_type = None
|
||||
if type.resolve_type:
|
||||
_resolve_type = partial(resolve_type, type.resolve_type, map, type._meta.name)
|
||||
map[type._meta.name] = GrapheneInterfaceType(
|
||||
return GrapheneInterfaceType(
|
||||
graphene_type=type,
|
||||
name=type._meta.name,
|
||||
description=type._meta.description,
|
||||
fields=None,
|
||||
fields=partial(self.construct_fields_for_type, map, type),
|
||||
resolve_type=_resolve_type,
|
||||
)
|
||||
map[type._meta.name]._fields = self.construct_fields_for_type(map, type)
|
||||
# self.reducer(map, map[type._meta.name])
|
||||
return map
|
||||
|
||||
def construct_inputobjecttype(self, map, type):
|
||||
map[type._meta.name] = GrapheneInputObjectType(
|
||||
return GrapheneInputObjectType(
|
||||
graphene_type=type,
|
||||
name=type._meta.name,
|
||||
description=type._meta.description,
|
||||
fields=None,
|
||||
fields=partial(self.construct_fields_for_type, map, type, is_input_type=True),
|
||||
)
|
||||
map[type._meta.name]._fields = self.construct_fields_for_type(map, type, is_input_type=True)
|
||||
return map
|
||||
|
||||
def construct_union(self, map, type):
|
||||
_resolve_type = None
|
||||
|
@ -179,16 +183,14 @@ class TypeMap(GraphQLTypeMap):
|
|||
_resolve_type = partial(resolve_type, type.resolve_type, map, type._meta.name)
|
||||
types = []
|
||||
for i in type._meta.types:
|
||||
map = self.construct_objecttype(map, i)
|
||||
types.append(map[i._meta.name])
|
||||
map[type._meta.name] = GrapheneUnionType(
|
||||
internal_type = self.construct_objecttype(map, i)
|
||||
types.append(internal_type)
|
||||
return GrapheneUnionType(
|
||||
graphene_type=type,
|
||||
name=type._meta.name,
|
||||
types=types,
|
||||
resolve_type=_resolve_type,
|
||||
)
|
||||
map[type._meta.name].types = types
|
||||
return map
|
||||
|
||||
def get_name(self, name):
|
||||
if self.auto_camelcase:
|
||||
|
@ -202,7 +204,7 @@ class TypeMap(GraphQLTypeMap):
|
|||
fields = OrderedDict()
|
||||
for name, field in type._meta.fields.items():
|
||||
if isinstance(field, Dynamic):
|
||||
field = get_field_as(field.get_type(), _as=Field)
|
||||
field = get_field_as(field.get_type(self.schema), _as=Field)
|
||||
if not field:
|
||||
continue
|
||||
map = self.reducer(map, field.type)
|
||||
|
|
Loading…
Reference in New Issue
Block a user