mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-26 19:43:56 +03:00
Improved Mutation with custom Field and output
This commit is contained in:
parent
078230ad49
commit
f22504c2fc
|
@ -5,14 +5,14 @@ import six
|
||||||
|
|
||||||
from promise import Promise
|
from promise import Promise
|
||||||
|
|
||||||
from ..types import AbstractType, Argument, Field, InputObjectType, String
|
from ..types import Field, AbstractType, Argument, InputObjectType, String
|
||||||
from ..types.objecttype import ObjectType, ObjectTypeMeta
|
from ..types.mutation import Mutation, MutationMeta
|
||||||
|
from ..types.objecttype import ObjectTypeMeta
|
||||||
from ..utils.is_base_type import is_base_type
|
from ..utils.is_base_type import is_base_type
|
||||||
from ..utils.props import props
|
from ..utils.props import props
|
||||||
|
|
||||||
|
|
||||||
class ClientIDMutationMeta(ObjectTypeMeta):
|
class ClientIDMutationMeta(MutationMeta):
|
||||||
|
|
||||||
def __new__(cls, name, bases, attrs):
|
def __new__(cls, name, bases, attrs):
|
||||||
# Also ensure initialization is only performed for subclasses of
|
# Also ensure initialization is only performed for subclasses of
|
||||||
# Mutation
|
# Mutation
|
||||||
|
@ -23,13 +23,13 @@ class ClientIDMutationMeta(ObjectTypeMeta):
|
||||||
base_name = re.sub('Payload$', '', name)
|
base_name = re.sub('Payload$', '', name)
|
||||||
if 'client_mutation_id' not in attrs:
|
if 'client_mutation_id' not in attrs:
|
||||||
attrs['client_mutation_id'] = String(name='clientMutationId')
|
attrs['client_mutation_id'] = String(name='clientMutationId')
|
||||||
cls = ObjectTypeMeta.__new__(cls, '{}Payload'.format(base_name), bases, attrs)
|
cls = ObjectTypeMeta.__new__(cls, '{}Payload'.format(base_name), bases,
|
||||||
|
attrs)
|
||||||
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"
|
"{}.mutate_and_get_payload method is required"
|
||||||
" in a ClientIDMutation."
|
" in a ClientIDMutation.").format(name)
|
||||||
).format(name)
|
|
||||||
input_attrs = {}
|
input_attrs = {}
|
||||||
bases = ()
|
bases = ()
|
||||||
if not input_class:
|
if not input_class:
|
||||||
|
@ -39,13 +39,18 @@ class ClientIDMutationMeta(ObjectTypeMeta):
|
||||||
else:
|
else:
|
||||||
bases += (input_class, )
|
bases += (input_class, )
|
||||||
input_attrs['client_mutation_id'] = String(name='clientMutationId')
|
input_attrs['client_mutation_id'] = String(name='clientMutationId')
|
||||||
cls.Input = type('{}Input'.format(base_name), bases + (InputObjectType,), input_attrs)
|
cls.Input = type('{}Input'.format(base_name),
|
||||||
cls.Field = partial(Field, cls, resolver=cls.mutate, input=Argument(cls.Input, required=True))
|
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
|
return cls
|
||||||
|
|
||||||
|
|
||||||
class ClientIDMutation(six.with_metaclass(ClientIDMutationMeta, ObjectType)):
|
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')
|
||||||
|
@ -54,11 +59,10 @@ class ClientIDMutation(six.with_metaclass(ClientIDMutationMeta, ObjectType)):
|
||||||
try:
|
try:
|
||||||
payload.client_mutation_id = input.get('clientMutationId')
|
payload.client_mutation_id = input.get('clientMutationId')
|
||||||
except:
|
except:
|
||||||
raise Exception((
|
raise Exception(
|
||||||
'Cannot set client_mutation_id in the payload object {}'
|
('Cannot set client_mutation_id in the payload object {}'
|
||||||
).format(repr(payload)))
|
).format(repr(payload)))
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
return Promise.resolve(
|
return Promise.resolve(
|
||||||
cls.mutate_and_get_payload(input, context, info)
|
cls.mutate_and_get_payload(input, context, info)).then(on_resolve)
|
||||||
).then(on_resolve)
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ from .objecttype import ObjectType, ObjectTypeMeta
|
||||||
|
|
||||||
|
|
||||||
class MutationMeta(ObjectTypeMeta):
|
class MutationMeta(ObjectTypeMeta):
|
||||||
|
|
||||||
def __new__(cls, name, bases, attrs):
|
def __new__(cls, name, bases, attrs):
|
||||||
# Also ensure initialization is only performed for subclasses of
|
# Also ensure initialization is only performed for subclasses of
|
||||||
# Mutation
|
# Mutation
|
||||||
|
@ -21,10 +20,12 @@ class MutationMeta(ObjectTypeMeta):
|
||||||
|
|
||||||
cls = ObjectTypeMeta.__new__(cls, name, bases, attrs)
|
cls = ObjectTypeMeta.__new__(cls, name, bases, attrs)
|
||||||
field_args = props(input_class) if input_class else {}
|
field_args = props(input_class) if input_class else {}
|
||||||
|
output_class = getattr(cls, 'Output', cls)
|
||||||
resolver = getattr(cls, 'mutate', None)
|
resolver = getattr(cls, 'mutate', None)
|
||||||
assert resolver, 'All mutations must define a mutate method in it'
|
assert resolver, 'All mutations must define a mutate method in it'
|
||||||
resolver = get_unbound_function(resolver)
|
resolver = get_unbound_function(resolver)
|
||||||
cls.Field = partial(Field, cls, args=field_args, resolver=resolver)
|
cls.Field = partial(
|
||||||
|
Field, output_class, args=field_args, resolver=resolver)
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import pytest
|
||||||
from ..mutation import Mutation
|
from ..mutation import Mutation
|
||||||
from ..objecttype import ObjectType
|
from ..objecttype import ObjectType
|
||||||
from ..schema import Schema
|
from ..schema import Schema
|
||||||
|
from ..argument import Argument
|
||||||
from ..scalars import String
|
from ..scalars import String
|
||||||
from ..dynamic import Dynamic
|
from ..dynamic import Dynamic
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ from ..dynamic import Dynamic
|
||||||
def test_generate_mutation_no_args():
|
def test_generate_mutation_no_args():
|
||||||
class MyMutation(Mutation):
|
class MyMutation(Mutation):
|
||||||
'''Documentation'''
|
'''Documentation'''
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def mutate(cls, *args, **kwargs):
|
def mutate(cls, *args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
@ -22,7 +24,6 @@ def test_generate_mutation_no_args():
|
||||||
|
|
||||||
def test_generate_mutation_with_meta():
|
def test_generate_mutation_with_meta():
|
||||||
class MyMutation(Mutation):
|
class MyMutation(Mutation):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
name = 'MyOtherMutation'
|
name = 'MyOtherMutation'
|
||||||
description = 'Documentation'
|
description = 'Documentation'
|
||||||
|
@ -38,10 +39,33 @@ def test_generate_mutation_with_meta():
|
||||||
|
|
||||||
def test_mutation_raises_exception_if_no_mutate():
|
def test_mutation_raises_exception_if_no_mutate():
|
||||||
with pytest.raises(AssertionError) as excinfo:
|
with pytest.raises(AssertionError) as excinfo:
|
||||||
|
|
||||||
class MyMutation(Mutation):
|
class MyMutation(Mutation):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
assert "All mutations must define a mutate method in it" == str(excinfo.value)
|
assert "All mutations must define a mutate method in it" == str(
|
||||||
|
excinfo.value)
|
||||||
|
|
||||||
|
|
||||||
|
def test_mutation_custom_output_type():
|
||||||
|
class User(ObjectType):
|
||||||
|
name = String()
|
||||||
|
|
||||||
|
class CreateUser(Mutation):
|
||||||
|
class Input:
|
||||||
|
name = String()
|
||||||
|
|
||||||
|
Output = User
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def mutate(cls, args, context, info):
|
||||||
|
name = args.get('name')
|
||||||
|
return User(name=name)
|
||||||
|
|
||||||
|
field = CreateUser.Field()
|
||||||
|
assert field.type == User
|
||||||
|
assert field.args == {'name': Argument(String)}
|
||||||
|
assert field.resolver == CreateUser.mutate
|
||||||
|
|
||||||
|
|
||||||
def test_mutation_execution():
|
def test_mutation_execution():
|
||||||
|
|
Loading…
Reference in New Issue
Block a user