From e92b03bed5e1a12c558d5b1c8a03b92eecff3218 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Wed, 12 Apr 2017 23:23:44 -0700 Subject: [PATCH] Allow Node inner types to be lazy. Fixed #437 --- graphene/relay/node.py | 14 ++++++++------ graphene/relay/tests/test_node.py | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/graphene/relay/node.py b/graphene/relay/node.py index cf395058..aa6e2dc0 100644 --- a/graphene/relay/node.py +++ b/graphene/relay/node.py @@ -5,6 +5,7 @@ import six from graphql_relay import from_global_id, to_global_id from ..types import ID, Field, Interface, ObjectType +from ..types.utils import get_type from ..types.interface import InterfaceMeta @@ -64,17 +65,18 @@ class NodeField(Field): name=None, **kwargs): assert issubclass(node, Node), 'NodeField can only operate in Nodes' self.node_type = node - - # If we don's specify a type, the field type will be the node interface - field_type = type or node + self.field_type = type super(NodeField, self).__init__( - field_type, + # If we don's specify a type, the field type will be the node interface + type or node, description='The ID of the object', - id=ID(required=True), - resolver=partial(node.node_resolver, only_type=type) + id=ID(required=True) ) + def get_resolver(self, parent_resolver): + return partial(self.node_type.node_resolver, only_type=get_type(self.field_type)) + class Node(six.with_metaclass(NodeMeta, Interface)): '''An object with an ID''' diff --git a/graphene/relay/tests/test_node.py b/graphene/relay/tests/test_node.py index a72c512f..6a9c2e04 100644 --- a/graphene/relay/tests/test_node.py +++ b/graphene/relay/tests/test_node.py @@ -45,6 +45,7 @@ class RootQuery(ObjectType): first = String() node = Node.Field() only_node = Node.Field(MyNode) + only_node_lazy = Node.Field(lambda: MyNode) schema = Schema(query=RootQuery, types=[MyNode, MyOtherNode]) @@ -116,6 +117,23 @@ def test_node_field_only_type_wrong(): assert executed.data == { 'onlyNode': None } +def test_node_field_only_lazy_type(): + executed = schema.execute( + '{ onlyNodeLazy(id:"%s") { __typename, name } } ' % Node.to_global_id("MyNode", 1) + ) + assert not executed.errors + assert executed.data == {'onlyNodeLazy': {'__typename': 'MyNode', 'name': '1'}} + + +def test_node_field_only_lazy_type_wrong(): + executed = schema.execute( + '{ onlyNodeLazy(id:"%s") { __typename, name } } ' % Node.to_global_id("MyOtherNode", 1) + ) + assert len(executed.errors) == 1 + assert str(executed.errors[0]) == 'Must receive an MyOtherNode id.' + assert executed.data == { 'onlyNodeLazy': None } + + def test_str_schema(): assert str(schema) == """ schema { @@ -142,5 +160,6 @@ type RootQuery { first: String node(id: ID!): Node onlyNode(id: ID!): MyNode + onlyNodeLazy(id: ID!): MyNode } """.lstrip()