Skip to content

Commit 1795ed5

Browse files
committed
Merge branch 'master' of github.com:graphql-python/graphene
2 parents f119c3b + 42df4b6 commit 1795ed5

File tree

9 files changed

+72
-31
lines changed

9 files changed

+72
-31
lines changed

examples/starwars_django/schema.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class Meta:
1717
model = ShipModel
1818

1919
@classmethod
20-
def get_node(cls, id):
20+
def get_node(cls, id, info):
2121
return Ship(get_ship(id))
2222

2323

@@ -33,7 +33,7 @@ class Meta:
3333
model = FactionModel
3434

3535
@classmethod
36-
def get_node(cls, id):
36+
def get_node(cls, id, info):
3737
return Faction(get_faction(id))
3838

3939

examples/starwars_relay/schema.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class Ship(relay.Node):
1111
name = graphene.String(description='The name of the ship.')
1212

1313
@classmethod
14-
def get_node(cls, id):
14+
def get_node(cls, id, info):
1515
return get_ship(id)
1616

1717

@@ -27,7 +27,7 @@ def resolve_ships(self, **args):
2727
return [get_ship(ship_id) for ship_id in self.ships]
2828

2929
@classmethod
30-
def get_node(cls, id):
30+
def get_node(cls, id, info):
3131
return get_faction(id)
3232

3333

graphene/contrib/django/fields.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
class DjangoConnectionField(ConnectionField):
1111

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

1615

1716
class LazyListField(Field):
@@ -20,22 +19,23 @@ def get_type(self, schema):
2019
return List(self.type)
2120

2221
def resolver(self, instance, args, info):
23-
schema = info.schema.graphene_schema
2422
resolved = super(LazyListField, self).resolver(instance, args, info)
25-
return lazy_map(resolved, self.get_object_type(schema))
23+
return lazy_map(resolved, self.type)
2624

2725

2826
class ConnectionOrListField(Field):
2927

3028
def internal_type(self, schema):
3129
model_field = self.type
3230
field_object_type = model_field.get_object_type(schema)
31+
if not field_object_type:
32+
raise SkipField()
3333
if is_node(field_object_type):
34-
field = DjangoConnectionField(model_field)
34+
field = DjangoConnectionField(field_object_type)
3535
else:
36-
field = LazyListField(model_field)
36+
field = LazyListField(field_object_type)
3737
field.contribute_to_class(self.object_type, self.name)
38-
return field.internal_type(schema)
38+
return schema.T(field)
3939

4040

4141
class DjangoModelField(FieldType):

graphene/contrib/django/tests/test_query.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class Meta:
6666
model = Reporter
6767

6868
@classmethod
69-
def get_node(cls, id):
69+
def get_node(cls, id, info):
7070
return ReporterNode(Reporter(id=2, first_name='Cookie Monster'))
7171

7272
def resolve_articles(self, *args, **kwargs):
@@ -78,7 +78,7 @@ class Meta:
7878
model = Article
7979

8080
@classmethod
81-
def get_node(cls, id):
81+
def get_node(cls, id, info):
8282
return ArticleNode(Article(id=1, headline='Article node'))
8383

8484
class Query(graphene.ObjectType):

graphene/relay/fields.py

Lines changed: 6 additions & 5 deletions
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

@@ -91,7 +92,7 @@ def id_fetcher(self, global_id, info):
9192
object_type != self.field_object_type):
9293
return
9394

94-
return object_type.get_node(_id)
95+
return object_type.get_node(_id, info)
9596

9697
def resolver(self, instance, args, info):
9798
global_id = args.get('id')

graphene/relay/tests/test_query.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import pytest
12
from graphql.core.type import GraphQLID, GraphQLNonNull
23

34
import graphene
@@ -15,12 +16,22 @@ class MyNode(relay.Node):
1516
name = graphene.String()
1617

1718
@classmethod
18-
def get_node(cls, id):
19+
def get_node(cls, id, info):
1920
return MyNode(id=id, name='mo')
2021

2122

23+
class SpecialNode(relay.Node):
24+
value = graphene.String()
25+
26+
@classmethod
27+
def get_node(cls, id, info):
28+
value = "!!!" if info.request_context.get('is_special') else "???"
29+
return SpecialNode(id=id, value=value)
30+
31+
2232
class Query(graphene.ObjectType):
2333
my_node = relay.NodeField(MyNode)
34+
special_node = relay.NodeField(SpecialNode)
2435
all_my_nodes = relay.ConnectionField(
2536
MyNode, connection_type=MyConnection, customArg=graphene.String())
2637

@@ -79,6 +90,28 @@ def test_nodefield_query():
7990
assert result.data == expected
8091

8192

93+
@pytest.mark.parametrize('specialness,value', [(True, '!!!'), (False, '???')])
94+
def test_get_node_info(specialness, value):
95+
query = '''
96+
query ValueQuery {
97+
specialNode(id:"U3BlY2lhbE5vZGU6Mg==") {
98+
id
99+
value
100+
}
101+
}
102+
'''
103+
104+
expected = {
105+
'specialNode': {
106+
'id': 'U3BlY2lhbE5vZGU6Mg==',
107+
'value': value,
108+
},
109+
}
110+
result = schema.execute(query, request_context={'is_special': specialness})
111+
assert not result.errors
112+
assert result.data == expected
113+
114+
82115
def test_nodeidfield():
83116
id_field = MyNode._meta.fields_map['id']
84117
id_field_type = schema.T(id_field)

graphene/relay/tests/test_types.py

Lines changed: 13 additions & 0 deletions
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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from ..core.types import (Boolean, Field, InputObjectType, Interface, List,
44
Mutation, ObjectType, String)
55
from ..core.types.argument import ArgumentsGroup
6-
from ..core.types.base import LazyType
76
from ..core.types.definitions import NonNull
87
from ..utils import memoize
98
from .fields import GlobalIDField
@@ -24,11 +23,6 @@ class PageInfo(ObjectType):
2423

2524
class Edge(ObjectType):
2625
'''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')
3226
cursor = String(
3327
required=True, description='A cursor for use in pagination')
3428

@@ -37,10 +31,11 @@ class Meta:
3731
def for_node(cls, node):
3832
from graphene.relay.utils import is_node
3933
assert is_node(node), 'ObjectTypes in a edge have to be Nodes'
34+
node_field = Field(node, description='The item at the end of the edge')
4035
return type(
4136
'%s%s' % (node._meta.type_name, cls._meta.type_name),
4237
(cls,),
43-
{'node_type': node})
38+
{'node_type': node, 'node': node_field})
4439

4540

4641
class Connection(ObjectType):
@@ -50,21 +45,20 @@ class Meta:
5045

5146
page_info = Field(PageInfo, required=True,
5247
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.')
5548

5649
_connection_data = None
5750

5851
@classmethod
5952
@memoize
6053
def for_node(cls, node, edge_type=None):
6154
from graphene.relay.utils import is_node
62-
edge_type = edge_type or Edge
55+
edge_type = edge_type or Edge.for_node(node)
6356
assert is_node(node), 'ObjectTypes in a connection have to be Nodes'
57+
edges = List(edge_type, description='Information to aid in pagination.')
6458
return type(
6559
'%s%s' % (node._meta.type_name, cls._meta.type_name),
6660
(cls,),
67-
{'edge_type': edge_type.for_node(node)})
61+
{'edge_type': edge_type, 'edges': edges})
6862

6963
def set_connection_data(self, data):
7064
self._connection_data = data

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def run_tests(self):
2424

2525
setup(
2626
name='graphene',
27-
version='0.4.0',
27+
version='0.4.0.1',
2828

2929
description='Graphene: Python DSL for GraphQL',
3030
long_description=open('README.rst').read(),

0 commit comments

Comments
 (0)