mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-11-04 01:47:45 +03:00 
			
		
		
		
	Improved relay
This commit is contained in:
		
							parent
							
								
									cfba52e6f3
								
							
						
					
					
						commit
						b0f2b4dd55
					
				| 
						 | 
				
			
			@ -40,9 +40,9 @@ class Schema(object):
 | 
			
		|||
            if object_type not in self._types:
 | 
			
		||||
                internal_type = object_type.internal_type(self)
 | 
			
		||||
                self._types[object_type] = internal_type
 | 
			
		||||
                name = getattr(internal_type, 'name', None)
 | 
			
		||||
                if name:
 | 
			
		||||
                    self._types_names[name] = object_type
 | 
			
		||||
                is_objecttype = inspect.isclass(object_type) and issubclass(object_type, BaseObjectType)
 | 
			
		||||
                if is_objecttype:
 | 
			
		||||
                    self.register(object_type)
 | 
			
		||||
            return self._types[object_type]
 | 
			
		||||
        else:
 | 
			
		||||
            return object_type
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +65,10 @@ class Schema(object):
 | 
			
		|||
        return GraphQLSchema(self, query=self.T(self.query), mutation=self.T(self.mutation))
 | 
			
		||||
 | 
			
		||||
    def register(self, object_type):
 | 
			
		||||
        type_name = object_type._meta.type_name
 | 
			
		||||
        registered_object_type = self._types_names.get(type_name, None)
 | 
			
		||||
        if registered_object_type:
 | 
			
		||||
            assert registered_object_type == object_type, 'Type {} already registered with other object type'.format(type_name)
 | 
			
		||||
        self._types_names[object_type._meta.type_name] = object_type
 | 
			
		||||
        return object_type
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,14 +31,12 @@ class Field(OrderedType):
 | 
			
		|||
        if isinstance(type, six.string_types):
 | 
			
		||||
            type = LazyType(type)
 | 
			
		||||
        self.required = required
 | 
			
		||||
        if self.required:
 | 
			
		||||
            type = NonNull(type)
 | 
			
		||||
        self.type = type
 | 
			
		||||
        self.description = description
 | 
			
		||||
        args = OrderedDict(args or {}, **kwargs)
 | 
			
		||||
        self.arguments = ArgumentsGroup(*args_list, **args)
 | 
			
		||||
        self.object_type = None
 | 
			
		||||
        self.resolver = resolver
 | 
			
		||||
        self.resolver_fn = resolver
 | 
			
		||||
        self.default = default
 | 
			
		||||
 | 
			
		||||
    def contribute_to_class(self, cls, attname):
 | 
			
		||||
| 
						 | 
				
			
			@ -54,11 +52,11 @@ class Field(OrderedType):
 | 
			
		|||
 | 
			
		||||
    @property
 | 
			
		||||
    def resolver(self):
 | 
			
		||||
        return self._resolver or self.get_resolver_fn()
 | 
			
		||||
        return self.resolver_fn or self.get_resolver_fn()
 | 
			
		||||
 | 
			
		||||
    @resolver.setter
 | 
			
		||||
    def resolver(self, value):
 | 
			
		||||
        self._resolver = value
 | 
			
		||||
        self.resolver_fn = value
 | 
			
		||||
 | 
			
		||||
    def get_resolver_fn(self):
 | 
			
		||||
        resolve_fn_name = 'resolve_%s' % self.attname
 | 
			
		||||
| 
						 | 
				
			
			@ -70,6 +68,8 @@ class Field(OrderedType):
 | 
			
		|||
        return default_getter
 | 
			
		||||
 | 
			
		||||
    def get_type(self, schema):
 | 
			
		||||
        if self.required:
 | 
			
		||||
            return NonNull(self.type)
 | 
			
		||||
        return self.type
 | 
			
		||||
 | 
			
		||||
    def internal_type(self, schema):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
from collections import Iterable
 | 
			
		||||
 | 
			
		||||
from graphene.core.fields import Field, IDField
 | 
			
		||||
from graphene.core.types.scalars import String, ID
 | 
			
		||||
from graphene.core.types.scalars import String, ID, Int
 | 
			
		||||
from graphql.core.type import GraphQLArgument, GraphQLID, GraphQLNonNull
 | 
			
		||||
from graphql_relay.connection.arrayconnection import connection_from_list
 | 
			
		||||
from graphql_relay.node.node import from_global_id
 | 
			
		||||
| 
						 | 
				
			
			@ -14,8 +14,8 @@ class ConnectionField(Field):
 | 
			
		|||
        super(ConnectionField, self).__init__(field_type, resolver=resolver,
 | 
			
		||||
                                              before=String(),
 | 
			
		||||
                                              after=String(),
 | 
			
		||||
                                              first=String(),
 | 
			
		||||
                                              last=String(),
 | 
			
		||||
                                              first=Int(),
 | 
			
		||||
                                              last=Int(),
 | 
			
		||||
                                              description=description, **kwargs)
 | 
			
		||||
        self.connection_type = connection_type
 | 
			
		||||
        self.edge_type = edge_type
 | 
			
		||||
| 
						 | 
				
			
			@ -24,17 +24,18 @@ class ConnectionField(Field):
 | 
			
		|||
        return value
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def resolve(self, instance, args, info):
 | 
			
		||||
    def resolver(self, instance, args, info):
 | 
			
		||||
        from graphene.relay.types import PageInfo
 | 
			
		||||
        schema = info.schema.graphene_schema
 | 
			
		||||
 | 
			
		||||
        resolved = super(ConnectionField, self).resolve(instance, args, info)
 | 
			
		||||
        resolved = super(ConnectionField, self).resolver(instance, args, info)
 | 
			
		||||
        if resolved:
 | 
			
		||||
            resolved = self.wrap_resolved(resolved, instance, args, info)
 | 
			
		||||
            assert isinstance(
 | 
			
		||||
                resolved, Iterable), 'Resolved value from the connection field have to be iterable'
 | 
			
		||||
 | 
			
		||||
            node = self.get_object_type(schema)
 | 
			
		||||
            type = schema.T(self.type)
 | 
			
		||||
            node = schema.objecttype(type)
 | 
			
		||||
            connection_type = self.get_connection_type(node)
 | 
			
		||||
            edge_type = self.get_edge_type(node)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -81,14 +82,16 @@ class NodeField(Field):
 | 
			
		|||
 | 
			
		||||
        return object_type.get_node(_id)
 | 
			
		||||
 | 
			
		||||
    def resolve(self, instance, args, info):
 | 
			
		||||
    def resolver(self, instance, args, info):
 | 
			
		||||
        global_id = args.get('id')
 | 
			
		||||
        return self.id_fetcher(global_id, info)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GlobalIDField(IDField):
 | 
			
		||||
class GlobalIDField(Field):
 | 
			
		||||
    '''The ID of an object'''
 | 
			
		||||
    required = True
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super(GlobalIDField, self).__init__(ID(), *args, **kwargs)
 | 
			
		||||
        self.required = True
 | 
			
		||||
 | 
			
		||||
    def contribute_to_class(self, cls, name):
 | 
			
		||||
        from graphene.relay.utils import is_node, is_node_type
 | 
			
		||||
| 
						 | 
				
			
			@ -96,5 +99,5 @@ class GlobalIDField(IDField):
 | 
			
		|||
        assert in_node, 'GlobalIDField could only be inside a Node, but got %r' % cls
 | 
			
		||||
        super(GlobalIDField, self).contribute_to_class(cls, name)
 | 
			
		||||
 | 
			
		||||
    def resolve(self, instance, args, info):
 | 
			
		||||
    def resolver(self, instance, args, info):
 | 
			
		||||
        return self.object_type.to_global_id(instance, args, info)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ class MyNode(relay.Node):
 | 
			
		|||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_node(cls, id):
 | 
			
		||||
        return MyNode(name='mo')
 | 
			
		||||
        return MyNode(id=id, name='mo')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Query(graphene.ObjectType):
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +35,7 @@ def test_nodefield_query():
 | 
			
		|||
    query = '''
 | 
			
		||||
    query RebelsShipsQuery {
 | 
			
		||||
      myNode(id:"TXlOb2RlOjE=") {
 | 
			
		||||
        id
 | 
			
		||||
        name
 | 
			
		||||
      },
 | 
			
		||||
      allMyNodes (customArg:"1") {
 | 
			
		||||
| 
						 | 
				
			
			@ -52,6 +53,7 @@ def test_nodefield_query():
 | 
			
		|||
    '''
 | 
			
		||||
    expected = {
 | 
			
		||||
        'myNode': {
 | 
			
		||||
            'id': 'TXlOb2RlOjE=',
 | 
			
		||||
            'name': 'mo'
 | 
			
		||||
        },
 | 
			
		||||
        'allMyNodes': {
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user