Closed
Description
Now that Graphene 1.4 and Promise 2.0 are out, I am now using them on my Django application, particularly promise.DataLoader
, and I came across the fact that the DjangoConnectionField.connection_resolver
method is not compatible with Promises, but fortunately, solving that is trivial, thanks to some tactical copypasting:
from functools import partial
from promise import Promise
from django.db.models import QuerySet, Manager
from graphene_django.fields import DjangoConnectionField
from graphene.relay import PageInfo
from graphql_relay.connection.arrayconnection import connection_from_list_slice
class PromiseDjangoConnectionField(DjangoConnectionField):
@classmethod
def connection_from_iterable(cls, args, connection, default_manager, iterable):
if iterable is None:
iterable = default_manager
if isinstance(iterable, Manager):
iterable = iterable.get_queryset()
if isinstance(iterable, QuerySet):
if iterable is not default_manager:
default_queryset = default_manager.get_queryset()
iterable = default_queryset & iterable
_len = iterable.count()
else:
_len = len(iterable)
connection = connection_from_list_slice(
iterable,
args,
slice_start=0,
list_length=_len,
list_slice_length=_len,
connection_type=connection,
edge_type=connection.Edge,
pageinfo_type=PageInfo,
)
connection.iterable = iterable
connection.length = _len
return connection
@classmethod
def connection_resolver(cls, resolver, connection, default_manager, max_limit,
enforce_first_or_last, root, args, context, info):
first = args.get('first')
last = args.get('last')
if enforce_first_or_last:
assert first or last, (
'You must provide a `first` or `last` value to properly paginate the `{}` connection.'
).format(info.field_name)
if max_limit:
if first:
assert first <= max_limit, (
'Requesting {} records on the `{}` connection exceeds the `first` limit of {} records.'
).format(first, info.field_name, max_limit)
args['first'] = min(first, max_limit)
if last:
assert last <= max_limit, (
'Requesting {} records on the `{}` connection exceeds the `last` limit of {} records.'
).format(first, info.field_name, max_limit)
args['last'] = min(last, max_limit)
iterable = resolver(root, args, context, info)
connection_from_iterable = partial(
cls.connection_from_iterable,
args,
connection,
default_manager
)
if Promise.is_thenable(iterable):
return iterable.then(connection_from_iterable)
else:
return connection_from_iterable(iterable)
If @syrusakbary gives me the green light, I'll write a PR with a few tests. 😄
Metadata
Metadata
Assignees
Labels
No labels