|
5 | 5 | connection_definitions
|
6 | 6 | )
|
7 | 7 |
|
8 |
| -from graphene.core.types import Interface |
| 8 | +from graphene.core.types import Interface, ObjectType |
| 9 | +from graphene.core.fields import BooleanField, StringField, ListField, Field |
9 | 10 | from graphene.relay.fields import GlobalIDField
|
10 | 11 | from graphene.utils import memoize
|
11 | 12 |
|
@@ -35,3 +36,37 @@ def to_global_id(cls, instance, args, info):
|
35 | 36 | class Node(BaseNode, Interface):
|
36 | 37 | '''An object with an ID'''
|
37 | 38 | id = GlobalIDField()
|
| 39 | + |
| 40 | + |
| 41 | +class PageInfo(ObjectType): |
| 42 | + has_next_page = BooleanField(required=True, description='When paginating forwards, are there more items?') |
| 43 | + has_previous_page = BooleanField(required=True, description='When paginating backwards, are there more items?') |
| 44 | + start_cursor = StringField(description='When paginating backwards, the cursor to continue.') |
| 45 | + end_cursor = StringField(description='When paginating forwards, the cursor to continue.') |
| 46 | + |
| 47 | + |
| 48 | +class Edge(ObjectType): |
| 49 | + '''An edge in a connection.''' |
| 50 | + node = Field(lambda field: field.object_type.node_type, description='The item at the end of the edge') |
| 51 | + end_cursor = StringField(required=True, description='A cursor for use in pagination') |
| 52 | + |
| 53 | + @classmethod |
| 54 | + @memoize |
| 55 | + def for_node(cls, node): |
| 56 | + from graphene.relay.utils import is_node |
| 57 | + assert is_node(node), 'ObjectTypes in a edge have to be Nodes' |
| 58 | + return type('%sEdge' % node._meta.type_name, (cls, ), {'node_type': node}) |
| 59 | + |
| 60 | + |
| 61 | +class Connection(ObjectType): |
| 62 | + '''A connection to a list of items.''' |
| 63 | + page_info = Field(PageInfo, required=True, description='The Information to aid in pagination') |
| 64 | + edges = ListField(lambda field: field.object_type.edge_type, description='Information to aid in pagination.') |
| 65 | + |
| 66 | + @classmethod |
| 67 | + @memoize |
| 68 | + def for_node(cls, node, edge_type=None): |
| 69 | + from graphene.relay.utils import is_node |
| 70 | + edge_type = edge_type or Edge |
| 71 | + assert is_node(node), 'ObjectTypes in a connection have to be Nodes' |
| 72 | + return type('%sConnection' % node._meta.type_name, (cls, ), {'edge_type': edge_type.for_node(node)}) |
0 commit comments