mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 12:44:15 +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
|
@classmethod
|
||||||
def internal_type(cls, schema):
|
def internal_type(cls, schema):
|
||||||
if cls._meta.abstract:
|
|
||||||
raise Exception("Abstract Interfaces don't have a specific type.")
|
|
||||||
|
|
||||||
if not cls._meta.interface:
|
if not cls._meta.interface:
|
||||||
return super(Interface, cls).internal_type(schema)
|
return super(Interface, cls).internal_type(schema)
|
||||||
|
|
||||||
|
|
|
@ -90,11 +90,5 @@ class GlobalIDField(Field):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(GlobalIDField, self).__init__(NonNull(ID()), *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):
|
def resolver(self, instance, args, info):
|
||||||
return instance.to_global_id()
|
return instance.to_global_id()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import inspect
|
import inspect
|
||||||
|
import six
|
||||||
import warnings
|
import warnings
|
||||||
from collections import Iterable
|
from collections import Iterable
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
@ -6,8 +7,10 @@ from functools import wraps
|
||||||
from graphql_relay.connection.arrayconnection import connection_from_list
|
from graphql_relay.connection.arrayconnection import connection_from_list
|
||||||
from graphql_relay.node.node import to_global_id
|
from graphql_relay.node.node import to_global_id
|
||||||
|
|
||||||
from ..core.types import (Boolean, Field, InputObjectType, Interface, List,
|
from ..core.classtypes import InputObjectType, Interface, Mutation, ObjectType
|
||||||
Mutation, ObjectType, String)
|
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.argument import ArgumentsGroup
|
||||||
from ..core.types.definitions import NonNull
|
from ..core.types.definitions import NonNull
|
||||||
from ..utils import memoize
|
from ..utils import memoize
|
||||||
|
@ -83,13 +86,9 @@ class Connection(ObjectType):
|
||||||
return self._connection_data
|
return self._connection_data
|
||||||
|
|
||||||
|
|
||||||
class BaseNode(object):
|
class NodeMeta(InterfaceMeta):
|
||||||
|
def construct_get_node(cls):
|
||||||
@classmethod
|
get_node = getattr(cls, 'get_node', None)
|
||||||
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 get_node, 'get_node classmethod not found in %s Node' % cls
|
||||||
assert callable(get_node), 'get_node have to be callable'
|
assert callable(get_node), 'get_node have to be callable'
|
||||||
args = 3
|
args = 3
|
||||||
|
@ -111,6 +110,20 @@ class BaseNode(object):
|
||||||
|
|
||||||
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):
|
def to_global_id(self):
|
||||||
type_name = self._meta.type_name
|
type_name = self._meta.type_name
|
||||||
return to_global_id(type_name, self.id)
|
return to_global_id(type_name, self.id)
|
||||||
|
@ -127,27 +140,31 @@ class BaseNode(object):
|
||||||
return cls.edge_type
|
return cls.edge_type
|
||||||
|
|
||||||
|
|
||||||
class Node(BaseNode, Interface):
|
|
||||||
'''An object with an ID'''
|
|
||||||
id = GlobalIDField()
|
|
||||||
|
|
||||||
|
|
||||||
class MutationInputType(InputObjectType):
|
class MutationInputType(InputObjectType):
|
||||||
client_mutation_id = String(required=True)
|
client_mutation_id = String(required=True)
|
||||||
|
|
||||||
|
|
||||||
class ClientIDMutation(Mutation):
|
class RelayMutationMeta(MutationMeta):
|
||||||
client_mutation_id = String(required=True)
|
def construct(cls, *args, **kwargs):
|
||||||
|
cls = super(RelayMutationMeta, cls).construct(*args, **kwargs)
|
||||||
@classmethod
|
if not cls._meta.abstract:
|
||||||
def _construct_arguments(cls, items):
|
|
||||||
assert hasattr(
|
assert hasattr(
|
||||||
cls, 'mutate_and_get_payload'), 'You have to implement mutate_and_get_payload'
|
cls, 'mutate_and_get_payload'), 'You have to implement mutate_and_get_payload'
|
||||||
|
return cls
|
||||||
|
|
||||||
|
def construct_arguments(cls, items):
|
||||||
new_input_type = type('{}Input'.format(
|
new_input_type = type('{}Input'.format(
|
||||||
cls._meta.type_name), (MutationInputType, ), items)
|
cls._meta.type_name), (MutationInputType, ), items)
|
||||||
cls.add_to_class('input_type', new_input_type)
|
cls.add_to_class('input_type', new_input_type)
|
||||||
return ArgumentsGroup(input=NonNull(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
|
@classmethod
|
||||||
def mutate(cls, instance, args, info):
|
def mutate(cls, instance, args, info):
|
||||||
input = args.get('input')
|
input = args.get('input')
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
from .types import BaseNode
|
from .types import Node
|
||||||
|
|
||||||
|
|
||||||
def is_node(object_type):
|
def is_node(object_type):
|
||||||
return object_type and issubclass(
|
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):
|
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