mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 04:34:13 +03:00
Improved classtypes relay support
This commit is contained in:
parent
8abcaff02b
commit
5b3000f734
|
@ -40,9 +40,6 @@ class Interface(six.with_metaclass(InterfaceMeta, ObjectType)):
|
|||
|
||||
@classmethod
|
||||
def internal_type(cls, schema):
|
||||
if cls._meta.abstract:
|
||||
raise Exception("Abstract Interfaces don't have a specific type.")
|
||||
|
||||
if not cls._meta.interface:
|
||||
return super(Interface, cls).internal_type(schema)
|
||||
|
||||
|
|
|
@ -90,11 +90,5 @@ class GlobalIDField(Field):
|
|||
def __init__(self, *args, **kwargs):
|
||||
super(GlobalIDField, self).__init__(NonNull(ID()), *args, **kwargs)
|
||||
|
||||
def contribute_to_class(self, cls, name):
|
||||
from graphene.relay.utils import is_node, is_node_type
|
||||
in_node = is_node(cls) or is_node_type(cls)
|
||||
assert in_node, 'GlobalIDField could only be inside a Node, but got %r' % cls
|
||||
super(GlobalIDField, self).contribute_to_class(cls, name)
|
||||
|
||||
def resolver(self, instance, args, info):
|
||||
return instance.to_global_id()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import inspect
|
||||
import six
|
||||
import warnings
|
||||
from collections import Iterable
|
||||
from functools import wraps
|
||||
|
@ -6,8 +7,10 @@ from functools import wraps
|
|||
from graphql_relay.connection.arrayconnection import connection_from_list
|
||||
from graphql_relay.node.node import to_global_id
|
||||
|
||||
from ..core.types import (Boolean, Field, InputObjectType, Interface, List,
|
||||
Mutation, ObjectType, String)
|
||||
from ..core.classtypes import InputObjectType, Interface, Mutation, ObjectType
|
||||
from ..core.classtypes.mutation import MutationMeta
|
||||
from ..core.classtypes.interface import InterfaceMeta
|
||||
from ..core.types import Boolean, Field, List, String
|
||||
from ..core.types.argument import ArgumentsGroup
|
||||
from ..core.types.definitions import NonNull
|
||||
from ..utils import memoize
|
||||
|
@ -83,33 +86,43 @@ class Connection(ObjectType):
|
|||
return self._connection_data
|
||||
|
||||
|
||||
class BaseNode(object):
|
||||
class NodeMeta(InterfaceMeta):
|
||||
def construct_get_node(cls):
|
||||
get_node = getattr(cls, 'get_node', None)
|
||||
assert get_node, 'get_node classmethod not found in %s Node' % cls
|
||||
assert callable(get_node), 'get_node have to be callable'
|
||||
args = 3
|
||||
if isinstance(get_node, staticmethod):
|
||||
args -= 1
|
||||
|
||||
@classmethod
|
||||
def _prepare_class(cls):
|
||||
from graphene.relay.utils import is_node
|
||||
if is_node(cls):
|
||||
get_node = getattr(cls, 'get_node')
|
||||
assert get_node, 'get_node classmethod not found in %s Node' % cls
|
||||
assert callable(get_node), 'get_node have to be callable'
|
||||
args = 3
|
||||
if isinstance(get_node, staticmethod):
|
||||
args -= 1
|
||||
get_node_num_args = len(inspect.getargspec(get_node).args)
|
||||
if get_node_num_args < args:
|
||||
warnings.warn("get_node will receive also the info arg"
|
||||
" in future versions of graphene".format(cls.__name__),
|
||||
FutureWarning)
|
||||
|
||||
get_node_num_args = len(inspect.getargspec(get_node).args)
|
||||
if get_node_num_args < args:
|
||||
warnings.warn("get_node will receive also the info arg"
|
||||
" in future versions of graphene".format(cls.__name__),
|
||||
FutureWarning)
|
||||
@staticmethod
|
||||
@wraps(get_node)
|
||||
def wrapped_node(*node_args):
|
||||
if len(node_args) < args:
|
||||
node_args += (None, )
|
||||
return get_node(*node_args[:-1])
|
||||
|
||||
@staticmethod
|
||||
@wraps(get_node)
|
||||
def wrapped_node(*node_args):
|
||||
if len(node_args) < args:
|
||||
node_args += (None, )
|
||||
return get_node(*node_args[:-1])
|
||||
setattr(cls, 'get_node', wrapped_node)
|
||||
|
||||
setattr(cls, 'get_node', wrapped_node)
|
||||
def construct(cls, *args, **kwargs):
|
||||
cls = super(NodeMeta, cls).construct(*args, **kwargs)
|
||||
if not cls._meta.abstract:
|
||||
cls.construct_get_node()
|
||||
return cls
|
||||
|
||||
|
||||
class Node(six.with_metaclass(NodeMeta, Interface)):
|
||||
'''An object with an ID'''
|
||||
id = GlobalIDField()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def to_global_id(self):
|
||||
type_name = self._meta.type_name
|
||||
|
@ -127,27 +140,31 @@ class BaseNode(object):
|
|||
return cls.edge_type
|
||||
|
||||
|
||||
class Node(BaseNode, Interface):
|
||||
'''An object with an ID'''
|
||||
id = GlobalIDField()
|
||||
|
||||
|
||||
class MutationInputType(InputObjectType):
|
||||
client_mutation_id = String(required=True)
|
||||
|
||||
|
||||
class ClientIDMutation(Mutation):
|
||||
client_mutation_id = String(required=True)
|
||||
class RelayMutationMeta(MutationMeta):
|
||||
def construct(cls, *args, **kwargs):
|
||||
cls = super(RelayMutationMeta, cls).construct(*args, **kwargs)
|
||||
if not cls._meta.abstract:
|
||||
assert hasattr(
|
||||
cls, 'mutate_and_get_payload'), 'You have to implement mutate_and_get_payload'
|
||||
return cls
|
||||
|
||||
@classmethod
|
||||
def _construct_arguments(cls, items):
|
||||
assert hasattr(
|
||||
cls, 'mutate_and_get_payload'), 'You have to implement mutate_and_get_payload'
|
||||
def construct_arguments(cls, items):
|
||||
new_input_type = type('{}Input'.format(
|
||||
cls._meta.type_name), (MutationInputType, ), items)
|
||||
cls.add_to_class('input_type', new_input_type)
|
||||
return ArgumentsGroup(input=NonNull(new_input_type))
|
||||
|
||||
|
||||
class ClientIDMutation(six.with_metaclass(RelayMutationMeta, Mutation)):
|
||||
client_mutation_id = String(required=True)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
@classmethod
|
||||
def mutate(cls, instance, args, info):
|
||||
input = args.get('input')
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from .types import BaseNode
|
||||
from .types import Node
|
||||
|
||||
|
||||
def is_node(object_type):
|
||||
return object_type and issubclass(
|
||||
object_type, BaseNode) and not is_node_type(object_type)
|
||||
object_type, Node) and not object_type._meta.abstract
|
||||
|
||||
|
||||
def is_node_type(object_type):
|
||||
return BaseNode in object_type.__bases__
|
||||
return object_type and issubclass(
|
||||
object_type, Node) and object_type._meta.abstract
|
||||
|
|
Loading…
Reference in New Issue
Block a user