mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 20:54:16 +03:00
Improved relay integration and abstraction
This commit is contained in:
parent
4de77c95e1
commit
d3f98d75f6
|
@ -91,15 +91,11 @@ class IterableConnectionField(Field):
|
||||||
assert issubclass(connection_type, Connection), '{} type have to be a subclass of Connection'.format(str(self))
|
assert issubclass(connection_type, Connection), '{} type have to be a subclass of Connection'.format(str(self))
|
||||||
return connection_type
|
return connection_type
|
||||||
|
|
||||||
@property
|
def connection_resolver(self, root, args, context, info):
|
||||||
def resolver(self):
|
iterable = super(ConnectionField, self).resolver(root, args, context, info)
|
||||||
super_resolver = super(ConnectionField, self).resolver
|
|
||||||
|
|
||||||
def resolver(root, args, context, info):
|
|
||||||
iterable = super_resolver(root, args, context, info)
|
|
||||||
# if isinstance(resolved, self.type.graphene)
|
# if isinstance(resolved, self.type.graphene)
|
||||||
assert isinstance(
|
assert isinstance(
|
||||||
iterable, Iterable), 'Resolved value from the connection field have to be iterable'
|
iterable, Iterable), 'Resolved value from the connection field have to be iterable. Received "{}"'.format(iterable)
|
||||||
connection = connection_from_list(
|
connection = connection_from_list(
|
||||||
iterable,
|
iterable,
|
||||||
args,
|
args,
|
||||||
|
@ -107,7 +103,10 @@ class IterableConnectionField(Field):
|
||||||
edge_type=self.connection.Edge,
|
edge_type=self.connection.Edge,
|
||||||
)
|
)
|
||||||
return connection
|
return connection
|
||||||
return resolver
|
|
||||||
|
@property
|
||||||
|
def resolver(self):
|
||||||
|
return self.connection_resolver
|
||||||
|
|
||||||
@resolver.setter
|
@resolver.setter
|
||||||
def resolver(self, resolver):
|
def resolver(self, resolver):
|
||||||
|
|
|
@ -6,41 +6,59 @@ from graphql_relay import from_global_id, node_definitions, to_global_id
|
||||||
|
|
||||||
from ..types.field import Field
|
from ..types.field import Field
|
||||||
from ..types.interface import Interface
|
from ..types.interface import Interface
|
||||||
from ..types.objecttype import ObjectType, ObjectTypeMeta
|
from ..types.objecttype import ObjectType, ObjectTypeMeta, is_objecttype
|
||||||
from ..types.options import Options
|
from ..types.options import Options
|
||||||
from .connection import Connection
|
from .connection import Connection
|
||||||
|
|
||||||
|
|
||||||
|
# We inherit from ObjectTypeMeta as we want to allow
|
||||||
|
# inheriting from Node, and also ObjectType.
|
||||||
|
# Like class MyNode(Node): pass
|
||||||
|
# And class MyNodeImplementation(Node, ObjectType): pass
|
||||||
class NodeMeta(ObjectTypeMeta):
|
class NodeMeta(ObjectTypeMeta):
|
||||||
|
|
||||||
def __new__(cls, name, bases, attrs):
|
@staticmethod
|
||||||
cls = super(NodeMeta, cls).__new__(cls, name, bases, attrs)
|
def _get_interface_options(meta):
|
||||||
is_object_type = cls.is_object_type()
|
return Options(
|
||||||
if not is_object_type:
|
meta,
|
||||||
get_node_from_global_id = getattr(cls, 'get_node_from_global_id', None)
|
|
||||||
id_resolver = getattr(cls, 'id_resolver', None)
|
|
||||||
assert get_node_from_global_id, '{}.get_node_from_global_id method is required by the Node interface.'.format(cls.__name__)
|
|
||||||
node_interface, node_field = node_definitions(
|
|
||||||
get_node_from_global_id,
|
|
||||||
id_resolver=id_resolver,
|
|
||||||
)
|
)
|
||||||
cls._meta = Options(None, graphql_type=node_interface)
|
|
||||||
cls.Field = partial(
|
def __new__(cls, name, bases, attrs):
|
||||||
Field.copy_and_extend,
|
|
||||||
node_field,
|
if is_objecttype(bases):
|
||||||
type=node_field.type,
|
cls = super(NodeMeta, cls).__new__(cls, name, bases, attrs)
|
||||||
parent=cls,
|
|
||||||
_creation_counter=None)
|
|
||||||
else:
|
|
||||||
# The interface provided by node_definitions is not an instance
|
# The interface provided by node_definitions is not an instance
|
||||||
# of GrapheneInterfaceType, so it will have no graphql_type,
|
# of GrapheneInterfaceType, so it will have no graphql_type,
|
||||||
# so will not trigger Node.implements
|
# so will not trigger Node.implements
|
||||||
cls.implements(cls)
|
cls.implements(cls)
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
options = cls._get_interface_options(attrs.pop('Meta', None))
|
||||||
|
cls = type.__new__(cls, name, bases, dict(attrs, _meta=options))
|
||||||
|
|
||||||
|
get_node_from_global_id = getattr(cls, 'get_node_from_global_id', None)
|
||||||
|
id_resolver = getattr(cls, 'id_resolver', None)
|
||||||
|
assert get_node_from_global_id, '{}.get_node_from_global_id method is required by the Node interface.'.format(cls.__name__)
|
||||||
|
node_interface, node_field = node_definitions(
|
||||||
|
get_node_from_global_id,
|
||||||
|
id_resolver=id_resolver,
|
||||||
|
type_resolver=cls.resolve_type,
|
||||||
|
)
|
||||||
|
options.graphql_type = node_interface
|
||||||
|
cls.Field = partial(
|
||||||
|
Field.copy_and_extend,
|
||||||
|
node_field,
|
||||||
|
type=node_field.type,
|
||||||
|
parent=cls,
|
||||||
|
_creation_counter=None)
|
||||||
|
|
||||||
|
return cls
|
||||||
|
|
||||||
|
|
||||||
class Node(six.with_metaclass(NodeMeta, Interface)):
|
class Node(six.with_metaclass(NodeMeta, Interface)):
|
||||||
_connection = None
|
_connection = None
|
||||||
|
resolve_type = None
|
||||||
|
use_global_id = True
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def require_get_node(cls):
|
def require_get_node(cls):
|
||||||
|
@ -48,15 +66,17 @@ class Node(six.with_metaclass(NodeMeta, Interface)):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_global_id(cls, global_id):
|
def from_global_id(cls, global_id):
|
||||||
if cls is Node:
|
|
||||||
return from_global_id(global_id)
|
return from_global_id(global_id)
|
||||||
raise NotImplementedError("You need to implement {}.from_global_id".format(cls.__name__))
|
# if cls is Node:
|
||||||
|
# return from_global_id(global_id)
|
||||||
|
# raise NotImplementedError("You need to implement {}.from_global_id".format(cls.__name__))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def to_global_id(cls, type, id):
|
def to_global_id(cls, type, id):
|
||||||
if cls is Node:
|
|
||||||
return to_global_id(type, id)
|
return to_global_id(type, id)
|
||||||
raise NotImplementedError("You need to implement {}.to_global_id".format(cls.__name__))
|
# if cls is Node:
|
||||||
|
# return to_global_id(type, id)
|
||||||
|
# raise NotImplementedError("You need to implement {}.to_global_id".format(cls.__name__))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def id_resolver(cls, root, args, context, info):
|
def id_resolver(cls, root, args, context, info):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user