Improved Node/Mutation fields

This commit is contained in:
Syrus Akbary 2016-06-09 22:37:20 -07:00
parent 9025b1c8f0
commit 522f769cad
8 changed files with 46 additions and 48 deletions

View File

@ -50,7 +50,7 @@ class IntroduceShip(relay.ClientIDMutation):
class Query(graphene.ObjectType):
rebels = graphene.Field(Faction)
empire = graphene.Field(Faction)
node = relay.Node.Field
node = relay.Node.Field()
@resolve_only_args
def resolve_rebels(self):
@ -62,7 +62,7 @@ class Query(graphene.ObjectType):
class Mutation(graphene.ObjectType):
introduce_ship = IntroduceShip.Field
introduce_ship = IntroduceShip.Field()

View File

@ -27,11 +27,11 @@ class ClientIDMutationMeta(MutationMeta):
def construct(cls, bases, attrs):
if not cls._meta.abstract:
Input = attrs.pop('Input', None)
field_attrs = props(Input) if Input else {}
input_fields = props(Input) if Input else {}
cls.mutate_and_get_payload = attrs.pop('mutate_and_get_payload', None)
input_local_fields = {f.name: f for f in InputObjectType._extract_local_fields(field_attrs)}
input_local_fields = {f.name: f for f in InputObjectType._extract_local_fields(input_fields)}
local_fields = cls._extract_local_fields(attrs)
assert cls.mutate_and_get_payload, "{}.mutate_and_get_payload method is required in a ClientIDMutation ObjectType.".format(cls.__name__)
field = mutation_with_client_mutation_id(
@ -46,16 +46,10 @@ class ClientIDMutationMeta(MutationMeta):
field_class=Field,
)
cls._meta.graphql_type = field.type
cls._Field = field
cls.Field = partial(Field.copy_and_extend, field, type=None, _creation_counter=None)
constructed = super(ClientIDMutationMeta, cls).construct(bases, attrs)
return constructed
@property
def Field(cls):
field = copy.copy(cls._Field)
field.reset_counter()
return field
class ClientIDMutation(six.with_metaclass(ClientIDMutationMeta, Mutation)):
class Meta:

View File

@ -21,17 +21,9 @@ class NodeMeta(ObjectTypeMeta):
field_class=Field,
)
cls._meta.graphql_type = node_interface
cls._Field = node_field
cls.Field = partial(Field.copy_and_extend, node_field, type=None, _creation_counter=None)
return super(NodeMeta, cls).construct(bases, attrs)
@property
def Field(cls):
# We put as a property for reset the field counter each time is called
# so it will be order correctly wherever is mounted
field = copy.copy(cls._Field)
field.reset_counter()
return field
class Node(six.with_metaclass(NodeMeta, Interface)):

View File

@ -23,7 +23,7 @@ class RootQuery(ObjectType):
class Mutation(ObjectType):
say = SaySomething.Field
say = SaySomething.Field()
schema = Schema(query=RootQuery, mutation=Mutation)
@ -40,8 +40,8 @@ def test_node_good():
graphql_type = SaySomething._meta.graphql_type
fields = graphql_type.get_fields()
assert 'phrase' in fields
assert SaySomething.Field.type == SaySomething._meta.graphql_type
graphql_field = SaySomething.Field
graphql_field = SaySomething.Field()
assert graphql_field.type == SaySomething._meta.graphql_type
assert 'input' in graphql_field.args
input = graphql_field.args['input']
assert 'clientMutationId' in input.type.of_type.get_fields()

View File

@ -18,7 +18,7 @@ class MyNode(ObjectType, Node):
class RootQuery(ObjectType):
first = String()
node = Node.Field
node = Node.Field()
schema = Schema(query=RootQuery, types=[MyNode])

View File

@ -35,7 +35,7 @@ photo_data = {
class RootQuery(ObjectType):
node = CustomNode.Field
node = CustomNode.Field()
schema = Schema(query=RootQuery, types=[User, Photo])

View File

@ -112,20 +112,25 @@ class Field(AbstractField, GraphQLField, OrderedType):
self._resolver = resolver
def __copy__(self):
field = self.__class__(
type=self._type,
args=self.args,
resolver=self._resolver,
source=self.source,
deprecation_reason=self.deprecation_reason,
name=self._name,
required=self.required,
description=self.description,
_creation_counter=self.creation_counter,
return self.copy_and_extend(self)
@classmethod
def copy_and_extend(cls, field, type=None, args=None, resolver=None, source=None, deprecation_reason=None, name=None, description=None, required=False, _creation_counter=False, **extra_args):
new_field = cls(
type=type or field._type,
args=to_arguments(args, field.args),
resolver=field._resolver,
source=source or getattr(field, 'source', None),
deprecation_reason=field.deprecation_reason,
name=field._name,
required=required or getattr(field, 'required', False),
description=field.description,
_creation_counter=getattr(field, 'creation_counter', None) if _creation_counter is False else None,
**extra_args
)
field.attname = self.attname
field.parent = self.parent
return field
new_field.attname = field.attname
new_field.parent = field.parent
return new_field
def __str__(self):
if not self.parent:
@ -159,13 +164,18 @@ class InputField(AbstractField, GraphQLInputObjectField, OrderedType):
self.parent = parent
def __copy__(self):
field = self.__class__(
type=self._type,
name=self._name,
required=self.required,
default_value=self.default_value,
description=self.description,
return self.copy_and_extend(self)
@classmethod
def copy_and_extend(cls, field, type=None, default_value=None, description=None, name=None, required=False, _creation_counter=False):
new_field = cls(
type=type or field._type,
name=name or field._name,
required=required or field.required,
default_value=default_value or field.default_value,
description=description or field.description,
_creation_counter=getattr(field, 'creation_counter', None) if _creation_counter is False else None,
)
field.attname = self.attname
field.parent = self.parent
return field
new_field.attname = field.attname
new_field.parent = field.parent
return new_field

View File

@ -20,6 +20,8 @@ def extract_fields(cls, attrs):
del attrs[attname]
_fields.append(field)
# All the fields are Graphene Fields or InputFields, so
# are orderable
return sorted(_fields)
@ -36,4 +38,4 @@ def get_base_fields(cls, bases):
fields.add(attname)
_fields.append(field)
return sorted(_fields)
return _fields