mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-10-29 23:17:47 +03:00 
			
		
		
		
	Merge branch 'master' of github.com:graphql-python/graphene
This commit is contained in:
		
						commit
						1795ed516c
					
				|  | @ -17,7 +17,7 @@ class Ship(DjangoNode): | |||
|         model = ShipModel | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_node(cls, id): | ||||
|     def get_node(cls, id, info): | ||||
|         return Ship(get_ship(id)) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -33,7 +33,7 @@ class Faction(DjangoNode): | |||
|         model = FactionModel | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_node(cls, id): | ||||
|     def get_node(cls, id, info): | ||||
|         return Faction(get_faction(id)) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ class Ship(relay.Node): | |||
|     name = graphene.String(description='The name of the ship.') | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_node(cls, id): | ||||
|     def get_node(cls, id, info): | ||||
|         return get_ship(id) | ||||
| 
 | ||||
| 
 | ||||
|  | @ -27,7 +27,7 @@ class Faction(relay.Node): | |||
|         return [get_ship(ship_id) for ship_id in self.ships] | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_node(cls, id): | ||||
|     def get_node(cls, id, info): | ||||
|         return get_faction(id) | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -10,8 +10,7 @@ from .utils import get_type_for_model, lazy_map | |||
| class DjangoConnectionField(ConnectionField): | ||||
| 
 | ||||
|     def wrap_resolved(self, value, instance, args, info): | ||||
|         schema = info.schema.graphene_schema | ||||
|         return lazy_map(value, self.type.get_object_type(schema)) | ||||
|         return lazy_map(value, self.type) | ||||
| 
 | ||||
| 
 | ||||
| class LazyListField(Field): | ||||
|  | @ -20,9 +19,8 @@ class LazyListField(Field): | |||
|         return List(self.type) | ||||
| 
 | ||||
|     def resolver(self, instance, args, info): | ||||
|         schema = info.schema.graphene_schema | ||||
|         resolved = super(LazyListField, self).resolver(instance, args, info) | ||||
|         return lazy_map(resolved, self.get_object_type(schema)) | ||||
|         return lazy_map(resolved, self.type) | ||||
| 
 | ||||
| 
 | ||||
| class ConnectionOrListField(Field): | ||||
|  | @ -30,12 +28,14 @@ class ConnectionOrListField(Field): | |||
|     def internal_type(self, schema): | ||||
|         model_field = self.type | ||||
|         field_object_type = model_field.get_object_type(schema) | ||||
|         if not field_object_type: | ||||
|             raise SkipField() | ||||
|         if is_node(field_object_type): | ||||
|             field = DjangoConnectionField(model_field) | ||||
|             field = DjangoConnectionField(field_object_type) | ||||
|         else: | ||||
|             field = LazyListField(model_field) | ||||
|             field = LazyListField(field_object_type) | ||||
|         field.contribute_to_class(self.object_type, self.name) | ||||
|         return field.internal_type(schema) | ||||
|         return schema.T(field) | ||||
| 
 | ||||
| 
 | ||||
| class DjangoModelField(FieldType): | ||||
|  |  | |||
|  | @ -66,7 +66,7 @@ def test_should_node(): | |||
|             model = Reporter | ||||
| 
 | ||||
|         @classmethod | ||||
|         def get_node(cls, id): | ||||
|         def get_node(cls, id, info): | ||||
|             return ReporterNode(Reporter(id=2, first_name='Cookie Monster')) | ||||
| 
 | ||||
|         def resolve_articles(self, *args, **kwargs): | ||||
|  | @ -78,7 +78,7 @@ def test_should_node(): | |||
|             model = Article | ||||
| 
 | ||||
|         @classmethod | ||||
|         def get_node(cls, id): | ||||
|         def get_node(cls, id, info): | ||||
|             return ArticleNode(Article(id=1, headline='Article node')) | ||||
| 
 | ||||
|     class Query(graphene.ObjectType): | ||||
|  |  | |||
|  | @ -10,12 +10,12 @@ from ..core.types.scalars import ID, Int, String | |||
| 
 | ||||
| class ConnectionField(Field): | ||||
| 
 | ||||
|     def __init__(self, field_type, resolver=None, description='', | ||||
|     def __init__(self, type, resolver=None, description='', | ||||
|                  connection_type=None, edge_type=None, **kwargs): | ||||
|         super( | ||||
|             ConnectionField, | ||||
|             self).__init__( | ||||
|             field_type, | ||||
|             type, | ||||
|             resolver=resolver, | ||||
|             before=String(), | ||||
|             after=String(), | ||||
|  | @ -38,7 +38,6 @@ class ConnectionField(Field): | |||
|             resolved = self.wrap_resolved(resolved, instance, args, info) | ||||
|             assert isinstance( | ||||
|                 resolved, Iterable), 'Resolved value from the connection field have to be iterable' | ||||
| 
 | ||||
|             type = schema.T(self.type) | ||||
|             node = schema.objecttype(type) | ||||
|             connection_type = self.get_connection_type(node) | ||||
|  | @ -56,7 +55,8 @@ class ConnectionField(Field): | |||
|         return connection_type.for_node(node, edge_type=edge_type) | ||||
| 
 | ||||
|     def get_edge_type(self, node): | ||||
|         return self.edge_type or node.get_edge_type() | ||||
|         edge_type = self.edge_type or node.get_edge_type() | ||||
|         return edge_type.for_node(node) | ||||
| 
 | ||||
|     def get_type(self, schema): | ||||
|         from graphene.relay.utils import is_node | ||||
|  | @ -65,6 +65,7 @@ class ConnectionField(Field): | |||
|         assert is_node(node), 'Only nodes have connections.' | ||||
|         schema.register(node) | ||||
|         connection_type = self.get_connection_type(node) | ||||
| 
 | ||||
|         return connection_type | ||||
| 
 | ||||
| 
 | ||||
|  | @ -91,7 +92,7 @@ class NodeField(Field): | |||
|                                         object_type != self.field_object_type): | ||||
|             return | ||||
| 
 | ||||
|         return object_type.get_node(_id) | ||||
|         return object_type.get_node(_id, info) | ||||
| 
 | ||||
|     def resolver(self, instance, args, info): | ||||
|         global_id = args.get('id') | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| import pytest | ||||
| from graphql.core.type import GraphQLID, GraphQLNonNull | ||||
| 
 | ||||
| import graphene | ||||
|  | @ -15,12 +16,22 @@ class MyNode(relay.Node): | |||
|     name = graphene.String() | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_node(cls, id): | ||||
|     def get_node(cls, id, info): | ||||
|         return MyNode(id=id, name='mo') | ||||
| 
 | ||||
| 
 | ||||
| class SpecialNode(relay.Node): | ||||
|     value = graphene.String() | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_node(cls, id, info): | ||||
|         value = "!!!" if info.request_context.get('is_special') else "???" | ||||
|         return SpecialNode(id=id, value=value) | ||||
| 
 | ||||
| 
 | ||||
| class Query(graphene.ObjectType): | ||||
|     my_node = relay.NodeField(MyNode) | ||||
|     special_node = relay.NodeField(SpecialNode) | ||||
|     all_my_nodes = relay.ConnectionField( | ||||
|         MyNode, connection_type=MyConnection, customArg=graphene.String()) | ||||
| 
 | ||||
|  | @ -79,6 +90,28 @@ def test_nodefield_query(): | |||
|     assert result.data == expected | ||||
| 
 | ||||
| 
 | ||||
| @pytest.mark.parametrize('specialness,value', [(True, '!!!'), (False, '???')]) | ||||
| def test_get_node_info(specialness, value): | ||||
|     query = ''' | ||||
|     query ValueQuery { | ||||
|       specialNode(id:"U3BlY2lhbE5vZGU6Mg==") { | ||||
|         id | ||||
|         value | ||||
|       } | ||||
|     } | ||||
|     ''' | ||||
| 
 | ||||
|     expected = { | ||||
|         'specialNode': { | ||||
|             'id': 'U3BlY2lhbE5vZGU6Mg==', | ||||
|             'value': value, | ||||
|         }, | ||||
|     } | ||||
|     result = schema.execute(query, request_context={'is_special': specialness}) | ||||
|     assert not result.errors | ||||
|     assert result.data == expected | ||||
| 
 | ||||
| 
 | ||||
| def test_nodeidfield(): | ||||
|     id_field = MyNode._meta.fields_map['id'] | ||||
|     id_field_type = schema.T(id_field) | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| from pytest import raises | ||||
| from graphql.core.type import GraphQLList | ||||
| 
 | ||||
| import graphene | ||||
| from graphene import relay | ||||
|  | @ -31,3 +32,15 @@ def test_node_should_have_same_connection_always(): | |||
| 
 | ||||
| def test_node_should_have_id_field(): | ||||
|     assert 'id' in OtherNode._meta.fields_map | ||||
| 
 | ||||
| 
 | ||||
| def test_node_connection_should_have_edge(): | ||||
|     connection = relay.Connection.for_node(OtherNode) | ||||
|     edge = relay.Edge.for_node(OtherNode) | ||||
|     connection_type = schema.T(connection) | ||||
|     connection_fields = connection_type.get_fields() | ||||
|     assert 'edges' in connection_fields | ||||
|     assert 'pageInfo' in connection_fields | ||||
|     edges_type = connection_fields['edges'].type | ||||
|     assert isinstance(edges_type, GraphQLList) | ||||
|     assert edges_type.of_type == schema.T(edge) | ||||
|  |  | |||
|  | @ -3,7 +3,6 @@ from graphql_relay.node.node import to_global_id | |||
| from ..core.types import (Boolean, Field, InputObjectType, Interface, List, | ||||
|                           Mutation, ObjectType, String) | ||||
| from ..core.types.argument import ArgumentsGroup | ||||
| from ..core.types.base import LazyType | ||||
| from ..core.types.definitions import NonNull | ||||
| from ..utils import memoize | ||||
| from .fields import GlobalIDField | ||||
|  | @ -24,11 +23,6 @@ class PageInfo(ObjectType): | |||
| 
 | ||||
| class Edge(ObjectType): | ||||
|     '''An edge in a connection.''' | ||||
|     class Meta: | ||||
|         type_name = 'DefaultEdge' | ||||
| 
 | ||||
|     node = Field(LazyType(lambda object_type: object_type.node_type), | ||||
|                  description='The item at the end of the edge') | ||||
|     cursor = String( | ||||
|         required=True, description='A cursor for use in pagination') | ||||
| 
 | ||||
|  | @ -37,10 +31,11 @@ class Edge(ObjectType): | |||
|     def for_node(cls, node): | ||||
|         from graphene.relay.utils import is_node | ||||
|         assert is_node(node), 'ObjectTypes in a edge have to be Nodes' | ||||
|         node_field = Field(node, description='The item at the end of the edge') | ||||
|         return type( | ||||
|             '%s%s' % (node._meta.type_name, cls._meta.type_name), | ||||
|             (cls,), | ||||
|             {'node_type': node}) | ||||
|             {'node_type': node, 'node': node_field}) | ||||
| 
 | ||||
| 
 | ||||
| class Connection(ObjectType): | ||||
|  | @ -50,8 +45,6 @@ class Connection(ObjectType): | |||
| 
 | ||||
|     page_info = Field(PageInfo, required=True, | ||||
|                       description='The Information to aid in pagination') | ||||
|     edges = List(LazyType(lambda object_type: object_type.edge_type), | ||||
|                  description='Information to aid in pagination.') | ||||
| 
 | ||||
|     _connection_data = None | ||||
| 
 | ||||
|  | @ -59,12 +52,13 @@ class Connection(ObjectType): | |||
|     @memoize | ||||
|     def for_node(cls, node, edge_type=None): | ||||
|         from graphene.relay.utils import is_node | ||||
|         edge_type = edge_type or Edge | ||||
|         edge_type = edge_type or Edge.for_node(node) | ||||
|         assert is_node(node), 'ObjectTypes in a connection have to be Nodes' | ||||
|         edges = List(edge_type, description='Information to aid in pagination.') | ||||
|         return type( | ||||
|             '%s%s' % (node._meta.type_name, cls._meta.type_name), | ||||
|             (cls,), | ||||
|             {'edge_type': edge_type.for_node(node)}) | ||||
|             {'edge_type': edge_type, 'edges': edges}) | ||||
| 
 | ||||
|     def set_connection_data(self, data): | ||||
|         self._connection_data = data | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user