mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-11-04 09:57:41 +03:00 
			
		
		
		
	Added Dynamic type (resolved in runtime)
This commit is contained in:
		
							parent
							
								
									99eec49a06
								
							
						
					
					
						commit
						f4062c3fc3
					
				| 
						 | 
					@ -9,7 +9,8 @@ from .types import (
 | 
				
			||||||
    String, ID, Int, Float, Boolean,
 | 
					    String, ID, Int, Float, Boolean,
 | 
				
			||||||
    List, NonNull,
 | 
					    List, NonNull,
 | 
				
			||||||
    Enum,
 | 
					    Enum,
 | 
				
			||||||
    Argument
 | 
					    Argument,
 | 
				
			||||||
 | 
					    Dynamic
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from .utils.resolve_only_args import resolve_only_args
 | 
					from .utils.resolve_only_args import resolve_only_args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,4 +31,5 @@ __all__ = [
 | 
				
			||||||
    'List',
 | 
					    'List',
 | 
				
			||||||
    'NonNull',
 | 
					    'NonNull',
 | 
				
			||||||
    'Argument',
 | 
					    'Argument',
 | 
				
			||||||
 | 
					    'Dynamic',
 | 
				
			||||||
    'resolve_only_args']
 | 
					    'resolve_only_args']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@ from .enum import Enum
 | 
				
			||||||
from .field import Field
 | 
					from .field import Field
 | 
				
			||||||
from .inputfield import InputField
 | 
					from .inputfield import InputField
 | 
				
			||||||
from .argument import Argument
 | 
					from .argument import Argument
 | 
				
			||||||
 | 
					from .dynamic import Dynamic
 | 
				
			||||||
from .inputobjecttype import InputObjectType
 | 
					from .inputobjecttype import InputObjectType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__all__ = [
 | 
					__all__ = [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								graphene/types/dynamic.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								graphene/types/dynamic.py
									
									
									
									
									
										Normal 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()
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,8 @@ import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..objecttype import ObjectType
 | 
					from ..objecttype import ObjectType
 | 
				
			||||||
from ..union import Union
 | 
					from ..union import Union
 | 
				
			||||||
 | 
					from ..field import Field
 | 
				
			||||||
 | 
					from ..dynamic import Dynamic
 | 
				
			||||||
from ..enum import Enum
 | 
					from ..enum import Enum
 | 
				
			||||||
from ..typemap import TypeMap
 | 
					from ..typemap import TypeMap
 | 
				
			||||||
from ..scalars import String
 | 
					from ..scalars import String
 | 
				
			||||||
| 
						 | 
					@ -63,3 +65,18 @@ def test_objecttype():
 | 
				
			||||||
    assert foo_field.args == {
 | 
					    assert foo_field.args == {
 | 
				
			||||||
        'bar': GraphQLArgument(GraphQLString, description='Argument description', default_value='x')
 | 
					        '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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@ from .inputobjecttype import InputObjectType
 | 
				
			||||||
from .structures import List, NonNull
 | 
					from .structures import List, NonNull
 | 
				
			||||||
from .enum import Enum
 | 
					from .enum import Enum
 | 
				
			||||||
from .scalars import Scalar, String, Boolean, Int, Float, ID
 | 
					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 import GraphQLString, GraphQLField, GraphQLList, GraphQLBoolean, GraphQLInt, GraphQLFloat, GraphQLID, GraphQLNonNull, GraphQLInputObjectField, GraphQLArgument
 | 
				
			||||||
from graphql.type import GraphQLEnumValue
 | 
					from graphql.type import GraphQLEnumValue
 | 
				
			||||||
| 
						 | 
					@ -189,6 +190,10 @@ class TypeMap(GraphQLTypeMap):
 | 
				
			||||||
    def construct_fields_for_type(cls, map, type, is_input_type=False):
 | 
					    def construct_fields_for_type(cls, map, type, is_input_type=False):
 | 
				
			||||||
        fields = OrderedDict()
 | 
					        fields = OrderedDict()
 | 
				
			||||||
        for name, field in type._meta.fields.items():
 | 
					        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)
 | 
					            map = cls.reducer(map, field.type)
 | 
				
			||||||
            field_type = cls.get_field_type(map, field.type)
 | 
					            field_type = cls.get_field_type(map, field.type)
 | 
				
			||||||
            if is_input_type:
 | 
					            if is_input_type:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@ from collections import OrderedDict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .unmountedtype import UnmountedType
 | 
					from .unmountedtype import UnmountedType
 | 
				
			||||||
from .field import Field
 | 
					from .field import Field
 | 
				
			||||||
 | 
					from .dynamic import Dynamic
 | 
				
			||||||
from .inputfield import InputField
 | 
					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):
 | 
					def get_fields_in_type(in_type, attrs):
 | 
				
			||||||
    fields_with_names = []
 | 
					    fields_with_names = []
 | 
				
			||||||
    for attname, value in list(attrs.items()):
 | 
					    for attname, value in list(attrs.items()):
 | 
				
			||||||
        if isinstance(value, (Field, InputField)):
 | 
					        if isinstance(value, (Field, InputField, Dynamic)):
 | 
				
			||||||
            fields_with_names.append(
 | 
					            fields_with_names.append(
 | 
				
			||||||
                (attname, value)
 | 
					                (attname, value)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user