mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 20:54:16 +03:00
Fixed relay ClientIDMutation
This commit is contained in:
parent
4820a7fede
commit
7a6d741531
|
@ -10,9 +10,7 @@ from promise import Promise, is_thenable
|
||||||
from ..types import (AbstractType, Boolean, Enum, Int, Interface, List, NonNull, Scalar, String,
|
from ..types import (AbstractType, Boolean, Enum, Int, Interface, List, NonNull, Scalar, String,
|
||||||
Union)
|
Union)
|
||||||
from ..types.field import Field
|
from ..types.field import Field
|
||||||
from ..types.objecttype import ObjectType, ObjectTypeMeta
|
from ..types.objecttype import ObjectType
|
||||||
from ..types.options import Options
|
|
||||||
from ..utils.is_base_type import is_base_type
|
|
||||||
from ..utils.props import props
|
from ..utils.props import props
|
||||||
from .node import is_node
|
from .node import is_node
|
||||||
|
|
||||||
|
@ -41,7 +39,7 @@ class PageInfo(ObjectType):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ConnectionMeta(ObjectTypeMeta):
|
class ConnectionMeta(type):
|
||||||
|
|
||||||
def __new__(cls, name, bases, attrs):
|
def __new__(cls, name, bases, attrs):
|
||||||
# Also ensure initialization is only performed for subclasses of Model
|
# Also ensure initialization is only performed for subclasses of Model
|
||||||
|
@ -89,7 +87,7 @@ class ConnectionMeta(ObjectTypeMeta):
|
||||||
return ObjectTypeMeta.__new__(cls, name, bases, attrs)
|
return ObjectTypeMeta.__new__(cls, name, bases, attrs)
|
||||||
|
|
||||||
|
|
||||||
class Connection(six.with_metaclass(ConnectionMeta, ObjectType)):
|
class Connection(ObjectType):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,56 +1,53 @@
|
||||||
import re
|
import re
|
||||||
from functools import partial
|
from collections import OrderedDict
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from promise import Promise
|
from promise import Promise
|
||||||
|
|
||||||
from ..types import Field, AbstractType, Argument, InputObjectType, String
|
from ..types import Field, AbstractType, Argument, InputObjectType, String, Field
|
||||||
from ..types.mutation import Mutation, MutationMeta
|
from ..types.mutation import Mutation, MutationOptions
|
||||||
from ..types.objecttype import ObjectTypeMeta
|
|
||||||
from ..utils.is_base_type import is_base_type
|
|
||||||
from ..utils.props import props
|
from ..utils.props import props
|
||||||
|
|
||||||
|
|
||||||
class ClientIDMutationMeta(MutationMeta):
|
class ClientIDMutation(Mutation):
|
||||||
def __new__(cls, name, bases, attrs):
|
class Meta:
|
||||||
# Also ensure initialization is only performed for subclasses of
|
abstract = True
|
||||||
# Mutation
|
|
||||||
if not is_base_type(bases, ClientIDMutationMeta):
|
|
||||||
return type.__new__(cls, name, bases, attrs)
|
|
||||||
|
|
||||||
input_class = attrs.pop('Input', None)
|
@classmethod
|
||||||
|
def __init_subclass_with_meta__(cls, output=None, arguments=None, name=None, **options):
|
||||||
|
input_class = getattr(cls, 'Input', None)
|
||||||
|
name = name or cls.__name__
|
||||||
base_name = re.sub('Payload$', '', name)
|
base_name = re.sub('Payload$', '', name)
|
||||||
if 'client_mutation_id' not in attrs:
|
|
||||||
attrs['client_mutation_id'] = String(name='clientMutationId')
|
assert not output, "Can't specify any output"
|
||||||
cls = ObjectTypeMeta.__new__(cls, '{}Payload'.format(base_name), bases,
|
assert not arguments, "Can't specify any arguments"
|
||||||
attrs)
|
|
||||||
|
bases = (InputObjectType, )
|
||||||
|
if input_class:
|
||||||
|
bases += (input_class, )
|
||||||
|
|
||||||
|
cls.Input = type('{}Input'.format(base_name),
|
||||||
|
bases, {
|
||||||
|
'client_mutation_id': String(name='clientMutationId')
|
||||||
|
})
|
||||||
|
|
||||||
|
arguments = OrderedDict(
|
||||||
|
input=cls.Input(required=True)
|
||||||
|
# 'client_mutation_id': String(name='clientMutationId')
|
||||||
|
)
|
||||||
mutate_and_get_payload = getattr(cls, 'mutate_and_get_payload', None)
|
mutate_and_get_payload = getattr(cls, 'mutate_and_get_payload', None)
|
||||||
if cls.mutate and cls.mutate.__func__ == ClientIDMutation.mutate.__func__:
|
if cls.mutate and cls.mutate.__func__ == ClientIDMutation.mutate.__func__:
|
||||||
assert mutate_and_get_payload, (
|
assert mutate_and_get_payload, (
|
||||||
"{}.mutate_and_get_payload method is required"
|
"{name}.mutate_and_get_payload method is required"
|
||||||
" in a ClientIDMutation.").format(name)
|
" in a ClientIDMutation.").format(name=name)
|
||||||
input_attrs = {}
|
|
||||||
bases = ()
|
if not name:
|
||||||
if not input_class:
|
name = '{}Payload'.format(base_name)
|
||||||
input_attrs = {}
|
|
||||||
elif not issubclass(input_class, AbstractType):
|
|
||||||
input_attrs = props(input_class)
|
|
||||||
else:
|
|
||||||
bases += (input_class, )
|
|
||||||
input_attrs['client_mutation_id'] = String(name='clientMutationId')
|
|
||||||
cls.Input = type('{}Input'.format(base_name),
|
|
||||||
bases + (InputObjectType, ), input_attrs)
|
|
||||||
output_class = getattr(cls, 'Output', cls)
|
|
||||||
cls.Field = partial(
|
|
||||||
Field,
|
|
||||||
output_class,
|
|
||||||
resolver=cls.mutate,
|
|
||||||
input=Argument(cls.Input, required=True))
|
|
||||||
return cls
|
|
||||||
|
|
||||||
|
super(ClientIDMutation, cls).__init_subclass_with_meta__(output=None, arguments=arguments, name=name, **options)
|
||||||
|
cls._meta.fields['client_mutation_id'] = (
|
||||||
|
Field(String, name='clientMutationId')
|
||||||
|
)
|
||||||
|
|
||||||
class ClientIDMutation(six.with_metaclass(ClientIDMutationMeta, Mutation)):
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def mutate(cls, root, args, context, info):
|
def mutate(cls, root, args, context, info):
|
||||||
input = args.get('input')
|
input = args.get('input')
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from ...types import (AbstractType, Argument, Field, InputField,
|
from ...types import ( Argument, Field, InputField, ID,
|
||||||
InputObjectType, NonNull, ObjectType, Schema)
|
InputObjectType, NonNull, ObjectType, Schema)
|
||||||
from ...types.scalars import String
|
from ...types.scalars import String
|
||||||
from ..mutation import ClientIDMutation
|
from ..mutation import ClientIDMutation
|
||||||
|
@ -8,14 +8,14 @@ from ..node import Node
|
||||||
from promise import Promise
|
from promise import Promise
|
||||||
|
|
||||||
|
|
||||||
class SharedFields(AbstractType):
|
class SharedFields(object):
|
||||||
shared = String()
|
shared = String()
|
||||||
|
|
||||||
|
|
||||||
class MyNode(ObjectType):
|
class MyNode(ObjectType):
|
||||||
class Meta:
|
# class Meta:
|
||||||
interfaces = (Node, )
|
# interfaces = (Node, )
|
||||||
|
id = ID()
|
||||||
name = String()
|
name = String()
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,18 +43,24 @@ class SaySomethingPromise(ClientIDMutation):
|
||||||
return Promise.resolve(SaySomething(phrase=str(what)))
|
return Promise.resolve(SaySomething(phrase=str(what)))
|
||||||
|
|
||||||
|
|
||||||
|
# MyEdge = MyNode.Connection.Edge
|
||||||
|
class MyEdge(ObjectType):
|
||||||
|
node = Field(MyNode)
|
||||||
|
cursor = String()
|
||||||
|
|
||||||
|
|
||||||
class OtherMutation(ClientIDMutation):
|
class OtherMutation(ClientIDMutation):
|
||||||
class Input(SharedFields):
|
class Input(SharedFields):
|
||||||
additional_field = String()
|
additional_field = String()
|
||||||
|
|
||||||
name = String()
|
name = String()
|
||||||
my_node_edge = Field(MyNode.Connection.Edge)
|
my_node_edge = Field(MyEdge)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def mutate_and_get_payload(cls, args, context, info):
|
def mutate_and_get_payload(cls, args, context, info):
|
||||||
shared = args.get('shared', '')
|
shared = args.get('shared', '')
|
||||||
additionalField = args.get('additionalField', '')
|
additionalField = args.get('additionalField', '')
|
||||||
edge_type = MyNode.Connection.Edge
|
edge_type = MyEdge
|
||||||
return OtherMutation(
|
return OtherMutation(
|
||||||
name=shared + additionalField,
|
name=shared + additionalField,
|
||||||
my_node_edge=edge_type(cursor='1', node=MyNode(name='name')))
|
my_node_edge=edge_type(cursor='1', node=MyNode(name='name')))
|
||||||
|
|
|
@ -6,4 +6,4 @@ class AbstractType(object):
|
||||||
|
|
||||||
def __init_subclass__(cls, *args, **kwargs):
|
def __init_subclass__(cls, *args, **kwargs):
|
||||||
print("Abstract type is deprecated")
|
print("Abstract type is deprecated")
|
||||||
super(AbstractType, cls).__init_subclass__(*args, **kwargs)
|
# super(AbstractType, cls).__init_subclass__(*args, **kwargs)
|
||||||
|
|
|
@ -20,8 +20,11 @@ class Mutation(ObjectType):
|
||||||
Mutation Type Definition
|
Mutation Type Definition
|
||||||
'''
|
'''
|
||||||
@classmethod
|
@classmethod
|
||||||
def __init_subclass_with_meta__(cls, resolver=None, output=None, arguments=None, **options):
|
def __init_subclass_with_meta__(cls, resolver=None, output=None, arguments=None, _meta=None, abstract=False, **options):
|
||||||
_meta = MutationOptions(cls)
|
if abstract:
|
||||||
|
return
|
||||||
|
if not _meta:
|
||||||
|
_meta = MutationOptions(cls)
|
||||||
|
|
||||||
output = output or getattr(cls, 'Output', None)
|
output = output or getattr(cls, 'Output', None)
|
||||||
fields = {}
|
fields = {}
|
||||||
|
@ -51,7 +54,11 @@ class Mutation(ObjectType):
|
||||||
assert mutate, 'All mutations must define a mutate method in it'
|
assert mutate, 'All mutations must define a mutate method in it'
|
||||||
resolver = get_unbound_function(mutate)
|
resolver = get_unbound_function(mutate)
|
||||||
|
|
||||||
_meta.fields = fields
|
if _meta.fields:
|
||||||
|
_meta.fields.update(fields)
|
||||||
|
else:
|
||||||
|
_meta.fields = fields
|
||||||
|
|
||||||
_meta.output = output
|
_meta.output = output
|
||||||
_meta.resolver = resolver
|
_meta.resolver = resolver
|
||||||
_meta.arguments = arguments
|
_meta.arguments = arguments
|
||||||
|
|
|
@ -42,7 +42,10 @@ class ObjectType(BaseType):
|
||||||
'Please use one or other.'
|
'Please use one or other.'
|
||||||
).format(name=cls.__name__)
|
).format(name=cls.__name__)
|
||||||
|
|
||||||
_meta.fields = fields
|
if _meta.fields:
|
||||||
|
_meta.fields.update(fields)
|
||||||
|
else:
|
||||||
|
_meta.fields = fields
|
||||||
_meta.interfaces = interfaces
|
_meta.interfaces = interfaces
|
||||||
_meta.possible_types = possible_types
|
_meta.possible_types = possible_types
|
||||||
_meta.default_resolver = default_resolver
|
_meta.default_resolver = default_resolver
|
||||||
|
|
Loading…
Reference in New Issue
Block a user