Adding Promise support for DjangoConnectionField
See original GitHub issueNow 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. 😄
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:20 (1 by maintainers)
Top Results From Across the Web
How to combine DjangoObjectType and an additional field in ...
I need to add another field that is not in ExampleType to the query ... However, I'm getting many errors such as DjangoConnectionField...
Read more >Django + GraphQL. Solving N+1 Problem using DataLoaders
from graphene_django import DjangoConnectionField, DjangoObjectType ... of keys and returns a Promise which resolves to a list of values:.
Read more >Solving N+1 in GraphQL Python With Dataloader - Jerry Ng
Collects a list of keys (object IDs); Calls a batch loading function with the list of keys; Returns a Promise which resolves to...
Read more >graphene Changelog - pyup.io
Dependency on unused promise Library was removed: 1476 by mike-roberts-healx - Docs improvements by rgroothuijsen. All Changes * feat: Add support for ...
Read more >How to use the graphene-django.graphene_django.fields ...
To help you get started, we've selected a few graphene-django.graphene_django.fields.DjangoConnectionField examples, based on popular ways it is used in ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
This won’t solve n+1, no where in computer science can n+1 be solved only alleviated. not even quantum computers will solve n+1;
DataLoaders will help if for some reason you keep requesting the same item multiple times per query. But usually it’s nested queries that causes the exponential growth … so prefetching and select_related is your best option. But there is an open bug on how graphene-django throws away prefetched data … so …
@here or @Xzya Did you manage to get it working with
DjangoFilterConnectionField
?