Support Connections created from Promises

This commit is contained in:
arianon@openmailbox.org 2017-05-19 19:12:28 -04:00
parent afec960e4d
commit 4350582c52
3 changed files with 147 additions and 0 deletions

View File

@ -2,6 +2,8 @@ from functools import partial
from django.db.models.query import QuerySet
from promise import Promise
from graphene.types import Field, List
from graphene.relay import ConnectionField, PageInfo
from graphql_relay.connection.arrayconnection import connection_from_list_slice
@ -84,6 +86,7 @@ class DjangoConnectionField(ConnectionField):
args['last'] = min(last, max_limit)
iterable = resolver(root, args, context, info)
iterable = Promise.resolve(iterable).get()
if iterable is None:
iterable = default_manager
iterable = maybe_queryset(iterable)

View File

@ -545,3 +545,146 @@ def test_should_error_if_first_is_greater_than_max():
assert result.data == expected
graphene_settings.RELAY_CONNECTION_ENFORCE_FIRST_OR_LAST = False
def test_should_query_promise_connectionfields():
from promise import Promise
class ReporterType(DjangoObjectType):
class Meta:
model = Reporter
interfaces = (Node, )
class Query(graphene.ObjectType):
all_reporters = DjangoConnectionField(ReporterType)
def resolve_all_reporters(self, *args, **kwargs):
return Promise.resolve([Reporter(id=1)])
schema = graphene.Schema(query=Query)
query = '''
query ReporterPromiseConnectionQuery {
allReporters(first: 1) {
edges {
node {
id
}
}
}
}
'''
expected = {
'allReporters': {
'edges': [{
'node': {
'id': 'UmVwb3J0ZXJUeXBlOjE='
}
}]
}
}
result = schema.execute(query)
assert not result.errors
assert result.data == expected
def test_should_query_dataloader_fields():
from promise import Promise
from promise.dataloader import DataLoader
def article_batch_load_fn(keys):
queryset = Article.objects.filter(reporter_id__in=keys)
return Promise.resolve([
[article for article in queryset if article.reporter_id == id]
for id in keys
])
article_loader = DataLoader(article_batch_load_fn)
class ArticleType(DjangoObjectType):
class Meta:
model = Article
interfaces = (Node, )
class ReporterType(DjangoObjectType):
class Meta:
model = Reporter
interfaces = (Node, )
articles = DjangoConnectionField(ArticleType)
def resolve_articles(self, *args, **kwargs):
return article_loader.load(self.id)
class Query(graphene.ObjectType):
all_reporters = DjangoConnectionField(ReporterType)
r = Reporter.objects.create(
first_name='John',
last_name='Doe',
email='johndoe@example.com',
a_choice=1
)
Article.objects.create(
headline='Article Node 1',
pub_date=datetime.date.today(),
reporter=r,
editor=r,
lang='es'
)
Article.objects.create(
headline='Article Node 2',
pub_date=datetime.date.today(),
reporter=r,
editor=r,
lang='en'
)
schema = graphene.Schema(query=Query)
query = '''
query ReporterPromiseConnectionQuery {
allReporters(first: 1) {
edges {
node {
id
articles(first: 2) {
edges {
node {
headline
}
}
}
}
}
}
}
'''
expected = {
'allReporters': {
'edges': [{
'node': {
'id': 'UmVwb3J0ZXJUeXBlOjE=',
'articles': {
'edges': [{
'node': {
'headline': 'Article Node 1',
}
}, {
'node': {
'headline': 'Article Node 2'
}
}]
}
}
}]
}
}
result = schema.execute(query)
assert not result.errors
assert result.data == expected

View File

@ -47,6 +47,7 @@ setup(
'Django>=1.6.0',
'iso8601',
'singledispatch>=3.4.0.3',
'promise>=2.0',
],
setup_requires=[
'pytest-runner',