Allow Node inner types to be lazy. Fixed #437

This commit is contained in:
Syrus Akbary 2017-04-12 23:23:44 -07:00
parent 5f71ac7d41
commit e92b03bed5
2 changed files with 27 additions and 6 deletions

View File

@ -5,6 +5,7 @@ import six
from graphql_relay import from_global_id, to_global_id from graphql_relay import from_global_id, to_global_id
from ..types import ID, Field, Interface, ObjectType from ..types import ID, Field, Interface, ObjectType
from ..types.utils import get_type
from ..types.interface import InterfaceMeta from ..types.interface import InterfaceMeta
@ -64,17 +65,18 @@ class NodeField(Field):
name=None, **kwargs): name=None, **kwargs):
assert issubclass(node, Node), 'NodeField can only operate in Nodes' assert issubclass(node, Node), 'NodeField can only operate in Nodes'
self.node_type = node self.node_type = node
self.field_type = type
# If we don's specify a type, the field type will be the node interface
field_type = type or node
super(NodeField, self).__init__( 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', description='The ID of the object',
id=ID(required=True), id=ID(required=True)
resolver=partial(node.node_resolver, only_type=type)
) )
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)): class Node(six.with_metaclass(NodeMeta, Interface)):
'''An object with an ID''' '''An object with an ID'''

View File

@ -45,6 +45,7 @@ class RootQuery(ObjectType):
first = String() first = String()
node = Node.Field() node = Node.Field()
only_node = Node.Field(MyNode) only_node = Node.Field(MyNode)
only_node_lazy = Node.Field(lambda: MyNode)
schema = Schema(query=RootQuery, types=[MyNode, MyOtherNode]) schema = Schema(query=RootQuery, types=[MyNode, MyOtherNode])
@ -116,6 +117,23 @@ def test_node_field_only_type_wrong():
assert executed.data == { 'onlyNode': None } 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(): def test_str_schema():
assert str(schema) == """ assert str(schema) == """
schema { schema {
@ -142,5 +160,6 @@ type RootQuery {
first: String first: String
node(id: ID!): Node node(id: ID!): Node
onlyNode(id: ID!): MyNode onlyNode(id: ID!): MyNode
onlyNodeLazy(id: ID!): MyNode
} }
""".lstrip() """.lstrip()