Added Dynamic type (resolved in runtime)

This commit is contained in:
Syrus Akbary 2016-08-14 02:19:03 -07:00
parent 99eec49a06
commit f4062c3fc3
6 changed files with 41 additions and 2 deletions

View File

@ -9,7 +9,8 @@ from .types import (
String, ID, Int, Float, Boolean,
List, NonNull,
Enum,
Argument
Argument,
Dynamic
)
from .utils.resolve_only_args import resolve_only_args
@ -30,4 +31,5 @@ __all__ = [
'List',
'NonNull',
'Argument',
'Dynamic',
'resolve_only_args']

View File

@ -8,6 +8,7 @@ from .enum import Enum
from .field import Field
from .inputfield import InputField
from .argument import Argument
from .dynamic import Dynamic
from .inputobjecttype import InputObjectType
__all__ = [

13
graphene/types/dynamic.py Normal file
View File

@ -0,0 +1,13 @@
import inspect
from ..utils.orderedtype import OrderedType
class Dynamic(OrderedType):
def __init__(self, type, _creation_counter=None):
super(Dynamic, self).__init__(_creation_counter=_creation_counter)
assert inspect.isfunction(type)
self.type = type
def get_type(self):
return self.type()

View File

@ -2,6 +2,8 @@ import pytest
from ..objecttype import ObjectType
from ..union import Union
from ..field import Field
from ..dynamic import Dynamic
from ..enum import Enum
from ..typemap import TypeMap
from ..scalars import String
@ -63,3 +65,18 @@ def test_objecttype():
assert foo_field.args == {
'bar': GraphQLArgument(GraphQLString, description='Argument description', default_value='x')
}
def test_dynamic_objecttype():
class MyObjectType(ObjectType):
'''Description'''
bar = Dynamic(lambda: Field(String))
typemap = TypeMap([MyObjectType])
assert 'MyObjectType' in typemap
assert MyObjectType._meta.fields.keys() == ['bar']
graphql_type = typemap['MyObjectType']
fields = graphql_type.get_fields()
assert fields.keys() == ['bar']
assert fields['bar'].type == GraphQLString

View File

@ -11,6 +11,7 @@ from .inputobjecttype import InputObjectType
from .structures import List, NonNull
from .enum import Enum
from .scalars import Scalar, String, Boolean, Int, Float, ID
from .dynamic import Dynamic
from graphql import GraphQLString, GraphQLField, GraphQLList, GraphQLBoolean, GraphQLInt, GraphQLFloat, GraphQLID, GraphQLNonNull, GraphQLInputObjectField, GraphQLArgument
from graphql.type import GraphQLEnumValue
@ -189,6 +190,10 @@ class TypeMap(GraphQLTypeMap):
def construct_fields_for_type(cls, map, type, is_input_type=False):
fields = OrderedDict()
for name, field in type._meta.fields.items():
if isinstance(field, Dynamic):
field = field.get_type()
if not field:
continue
map = cls.reducer(map, field.type)
field_type = cls.get_field_type(map, field.type)
if is_input_type:

View File

@ -2,6 +2,7 @@ from collections import OrderedDict
from .unmountedtype import UnmountedType
from .field import Field
from .dynamic import Dynamic
from .inputfield import InputField
@ -50,7 +51,7 @@ def unmounted_field_in_type(attname, unmounted_field, type):
def get_fields_in_type(in_type, attrs):
fields_with_names = []
for attname, value in list(attrs.items()):
if isinstance(value, (Field, InputField)):
if isinstance(value, (Field, InputField, Dynamic)):
fields_with_names.append(
(attname, value)
)