Skip to content

Commit 266dd5e

Browse files
committed
Fixed relay connections/edges field mapping. Improved testing
1 parent 9b635c8 commit 266dd5e

File tree

4 files changed

+30
-19
lines changed

4 files changed

+30
-19
lines changed

graphene/contrib/django/fields.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class DjangoConnectionField(ConnectionField):
1111

1212
def wrap_resolved(self, value, instance, args, info):
1313
schema = info.schema.graphene_schema
14-
return lazy_map(value, self.type.get_object_type(schema))
14+
return lazy_map(value, self.type)
1515

1616

1717
class LazyListField(Field):
@@ -22,20 +22,22 @@ def get_type(self, schema):
2222
def resolver(self, instance, args, info):
2323
schema = info.schema.graphene_schema
2424
resolved = super(LazyListField, self).resolver(instance, args, info)
25-
return lazy_map(resolved, self.get_object_type(schema))
25+
return lazy_map(resolved, self.type)
2626

2727

2828
class ConnectionOrListField(Field):
2929

3030
def internal_type(self, schema):
3131
model_field = self.type
3232
field_object_type = model_field.get_object_type(schema)
33+
if not field_object_type:
34+
raise SkipField()
3335
if is_node(field_object_type):
34-
field = DjangoConnectionField(model_field)
36+
field = DjangoConnectionField(field_object_type)
3537
else:
36-
field = LazyListField(model_field)
38+
field = LazyListField(field_object_type)
3739
field.contribute_to_class(self.object_type, self.name)
38-
return field.internal_type(schema)
40+
return schema.T(field)
3941

4042

4143
class DjangoModelField(FieldType):

graphene/relay/fields.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010

1111
class ConnectionField(Field):
1212

13-
def __init__(self, field_type, resolver=None, description='',
13+
def __init__(self, type, resolver=None, description='',
1414
connection_type=None, edge_type=None, **kwargs):
1515
super(
1616
ConnectionField,
1717
self).__init__(
18-
field_type,
18+
type,
1919
resolver=resolver,
2020
before=String(),
2121
after=String(),
@@ -38,7 +38,6 @@ def resolver(self, instance, args, info):
3838
resolved = self.wrap_resolved(resolved, instance, args, info)
3939
assert isinstance(
4040
resolved, Iterable), 'Resolved value from the connection field have to be iterable'
41-
4241
type = schema.T(self.type)
4342
node = schema.objecttype(type)
4443
connection_type = self.get_connection_type(node)
@@ -56,7 +55,8 @@ def get_connection_type(self, node):
5655
return connection_type.for_node(node, edge_type=edge_type)
5756

5857
def get_edge_type(self, node):
59-
return self.edge_type or node.get_edge_type()
58+
edge_type = self.edge_type or node.get_edge_type()
59+
return edge_type.for_node(node)
6060

6161
def get_type(self, schema):
6262
from graphene.relay.utils import is_node
@@ -65,6 +65,7 @@ def get_type(self, schema):
6565
assert is_node(node), 'Only nodes have connections.'
6666
schema.register(node)
6767
connection_type = self.get_connection_type(node)
68+
6869
return connection_type
6970

7071

graphene/relay/tests/test_types.py

+13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from pytest import raises
2+
from graphql.core.type import GraphQLList
23

34
import graphene
45
from graphene import relay
@@ -31,3 +32,15 @@ def test_node_should_have_same_connection_always():
3132

3233
def test_node_should_have_id_field():
3334
assert 'id' in OtherNode._meta.fields_map
35+
36+
37+
def test_node_connection_should_have_edge():
38+
connection = relay.Connection.for_node(OtherNode)
39+
edge = relay.Edge.for_node(OtherNode)
40+
connection_type = schema.T(connection)
41+
connection_fields = connection_type.get_fields()
42+
assert 'edges' in connection_fields
43+
assert 'pageInfo' in connection_fields
44+
edges_type = connection_fields['edges'].type
45+
assert isinstance(edges_type, GraphQLList)
46+
assert edges_type.of_type == schema.T(edge)

graphene/relay/types.py

+5-10
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ class PageInfo(ObjectType):
2424

2525
class Edge(ObjectType):
2626
'''An edge in a connection.'''
27-
class Meta:
28-
type_name = 'DefaultEdge'
29-
30-
node = Field(LazyType(lambda object_type: object_type.node_type),
31-
description='The item at the end of the edge')
3227
cursor = String(
3328
required=True, description='A cursor for use in pagination')
3429

@@ -37,10 +32,11 @@ class Meta:
3732
def for_node(cls, node):
3833
from graphene.relay.utils import is_node
3934
assert is_node(node), 'ObjectTypes in a edge have to be Nodes'
35+
node_field = Field(node, description='The item at the end of the edge')
4036
return type(
4137
'%s%s' % (node._meta.type_name, cls._meta.type_name),
4238
(cls,),
43-
{'node_type': node})
39+
{'node_type': node, 'node': node_field})
4440

4541

4642
class Connection(ObjectType):
@@ -50,21 +46,20 @@ class Meta:
5046

5147
page_info = Field(PageInfo, required=True,
5248
description='The Information to aid in pagination')
53-
edges = List(LazyType(lambda object_type: object_type.edge_type),
54-
description='Information to aid in pagination.')
5549

5650
_connection_data = None
5751

5852
@classmethod
5953
@memoize
6054
def for_node(cls, node, edge_type=None):
6155
from graphene.relay.utils import is_node
62-
edge_type = edge_type or Edge
56+
edge_type = edge_type or Edge.for_node(node)
6357
assert is_node(node), 'ObjectTypes in a connection have to be Nodes'
58+
edges = List(edge_type, description='Information to aid in pagination.')
6459
return type(
6560
'%s%s' % (node._meta.type_name, cls._meta.type_name),
6661
(cls,),
67-
{'edge_type': edge_type.for_node(node)})
62+
{'edge_type': edge_type, 'edges': edges})
6863

6964
def set_connection_data(self, data):
7065
self._connection_data = data

0 commit comments

Comments
 (0)