First working version of mutations

This commit is contained in:
Syrus Akbary 2015-10-25 21:39:54 -07:00
parent 9e101898f1
commit 2648a2300b
8 changed files with 87 additions and 9 deletions

View File

@ -14,7 +14,8 @@ from graphene.core.schema import (
from graphene.core.types import (
ObjectType,
Interface
Interface,
Mutation,
)
from graphene.core.fields import (
@ -31,3 +32,8 @@ from graphene.core.fields import (
from graphene.decorators import (
resolve_only_args
)
__all__ = ['Enum', 'Argument', 'String', 'Int', 'ID', 'signals', 'Schema',
'ObjectType', 'Interface', 'Mutation', 'Field', 'StringField',
'IntField', 'BooleanField', 'IDField', 'ListField', 'NonNullField',
'FloatField', 'resolve_only_args']

View File

@ -51,14 +51,18 @@ class Field(object):
cls._meta.add_field(self)
def resolve(self, instance, args, info):
resolve_fn = self.get_resolve_fn()
schema = info and getattr(info.schema, 'graphene_schema', None)
resolve_fn = self.get_resolve_fn(schema)
if resolve_fn:
return resolve_fn(instance, args, info)
else:
return getattr(instance, self.field_name, None)
def get_resolve_fn(self):
if self.resolve_fn:
def get_resolve_fn(self, schema):
object_type = self.get_object_type(schema)
if object_type and object_type._meta.mutation:
return object_type.mutate
elif self.resolve_fn:
return self.resolve_fn
else:
custom_resolve_fn_name = 'resolve_%s' % self.field_name
@ -125,7 +129,7 @@ class Field(object):
raise Exception("Internal type for field %s is None" % self)
description = self.description
resolve_fn = self.get_resolve_fn()
resolve_fn = self.get_resolve_fn(schema)
if resolve_fn:
description = resolve_fn.__doc__ or description

View File

@ -1,7 +1,7 @@
from graphene.utils import cached_property
from collections import OrderedDict, namedtuple
DEFAULT_NAMES = ('description', 'name', 'interface',
DEFAULT_NAMES = ('description', 'name', 'interface', 'mutation',
'type_name', 'interfaces', 'proxy')
@ -11,6 +11,7 @@ class Options(object):
self.meta = meta
self.local_fields = []
self.interface = False
self.mutation = False
self.proxy = False
self.interfaces = []
self.parents = []

View File

@ -43,6 +43,15 @@ class Schema(object):
self._query = query
self._query_type = query and query.internal_type(self)
@property
def mutation(self):
return self._mutation
@mutation.setter
def mutation(self, mutation):
self._mutation = mutation
self._mutation_type = mutation and mutation.internal_type(self)
@property
def executor(self):
if not self._executor:
@ -57,7 +66,7 @@ class Schema(object):
def schema(self):
if not self._query_type:
raise Exception('You have to define a base query type')
return GraphQLSchema(self, query=self._query_type, mutation=self.mutation)
return GraphQLSchema(self, query=self._query_type, mutation=self._mutation_type)
def associate_internal_type(self, internal_type, object_type):
self._internal_types[internal_type.name] = object_type

View File

@ -55,6 +55,10 @@ class ObjectTypeMeta(type):
# Add all attributes to the class.
for obj_name, obj in attrs.items():
new_class.add_to_class(obj_name, obj)
if new_class._meta.mutation:
assert hasattr(new_class, 'mutate'), "All mutations must implement mutate method"
new_class.add_extra_fields()
new_fields = new_class._meta.local_fields

View File

@ -87,7 +87,7 @@ def test_field_resolve():
f = StringField(required=True, resolve=lambda *args: 'RESOLVED')
f.contribute_to_class(ot, 'field_name')
field_type = f.internal_field(schema)
assert 'RESOLVED' == field_type.resolver(ot, 2, 3)
assert 'RESOLVED' == field_type.resolver(ot, None, None)
def test_field_resolve_type_custom():

View File

@ -0,0 +1,54 @@
import graphene
from py.test import raises
from graphene.core.schema import Schema
my_id = 0
class Query(graphene.ObjectType):
base = graphene.StringField()
class ChangeNumber(graphene.Mutation):
'''Result mutation'''
class Input:
id = graphene.IntField(required=True)
result = graphene.StringField()
@classmethod
def mutate(cls, instance, args, info):
global my_id
my_id = my_id + 1
return ChangeNumber(result=my_id)
class MyResultMutation(graphene.ObjectType):
change_number = graphene.Field(ChangeNumber)
schema = Schema(query=Query, mutation=MyResultMutation)
def test_mutate():
query = '''
mutation M{
first: changeNumber {
result
},
second: changeNumber {
result
}
}
'''
expected = {
'first': {
'result': '1',
},
'second': {
'result': '2',
}
}
result = schema.execute(query, root=object())
assert not result.errors
assert result.data == expected

View File

@ -50,7 +50,7 @@ Human_type = Human.internal_type(schema)
def test_type():
assert Human._meta.fields_map['name'].resolve(Human(object()), 1, 2) == 'Peter'
assert Human._meta.fields_map['name'].resolve(Human(object()), None, None) == 'Peter'
def test_query():