mirror of
https://github.com/graphql-python/graphene-django.git
synced 2025-07-02 03:13:13 +03:00
Support Django Connection resolving in an async context
This commit is contained in:
parent
6a5b28d09f
commit
74998afb69
|
@ -9,7 +9,8 @@ from graphql_relay import (
|
||||||
offset_to_cursor,
|
offset_to_cursor,
|
||||||
)
|
)
|
||||||
|
|
||||||
from promise import Promise
|
from asgiref.sync import sync_to_async
|
||||||
|
from asyncio import get_running_loop
|
||||||
|
|
||||||
from graphene import Int, NonNull
|
from graphene import Int, NonNull
|
||||||
from graphene.relay import ConnectionField
|
from graphene.relay import ConnectionField
|
||||||
|
@ -228,20 +229,43 @@ class DjangoConnectionField(ConnectionField):
|
||||||
|
|
||||||
# eventually leads to DjangoObjectType's get_queryset (accepts queryset)
|
# eventually leads to DjangoObjectType's get_queryset (accepts queryset)
|
||||||
# or a resolve_foo (does not accept queryset)
|
# or a resolve_foo (does not accept queryset)
|
||||||
|
|
||||||
iterable = resolver(root, info, **args)
|
iterable = resolver(root, info, **args)
|
||||||
|
if info.is_awaitable(iterable):
|
||||||
|
async def await_result():
|
||||||
|
queryset_or_list = await iterable
|
||||||
|
if queryset_or_list is None:
|
||||||
|
queryset_or_list = default_manager
|
||||||
|
|
||||||
|
if is_async(queryset_resolver):
|
||||||
|
|
||||||
|
resolved = await sync_to_async(queryset_resolver)(connection, resolved, info, args)
|
||||||
|
|
||||||
|
# TODO: create an async_resolve_connection which uses the new Django queryset async functions
|
||||||
|
async_resolve_connection = sync_to_async(cls.resolve_connection)
|
||||||
|
|
||||||
|
if is_awaitable(resolved):
|
||||||
|
return async_resolve_connection(connection, args, await resolved, max_limit=max_limit)
|
||||||
|
|
||||||
|
return async_resolve_connection(connection, args, resolved, max_limit=max_limit)
|
||||||
|
|
||||||
|
return await_result()
|
||||||
|
|
||||||
if iterable is None:
|
if iterable is None:
|
||||||
iterable = default_manager
|
iterable = default_manager
|
||||||
# thus the iterable gets refiltered by resolve_queryset
|
# thus the iterable gets refiltered by resolve_queryset
|
||||||
# but iterable might be promise
|
# but iterable might be promise
|
||||||
iterable = queryset_resolver(connection, iterable, info, args)
|
iterable = queryset_resolver(connection, iterable, info, args)
|
||||||
on_resolve = partial(
|
|
||||||
cls.resolve_connection, connection, args, max_limit=max_limit
|
|
||||||
)
|
|
||||||
|
|
||||||
if Promise.is_thenable(iterable):
|
try:
|
||||||
return Promise.resolve(iterable).then(on_resolve)
|
get_running_loop()
|
||||||
|
except RuntimeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return sync_to_async(cls.resolve_connection)(connection, args, iterable, max_limit=max_limit)
|
||||||
|
|
||||||
return on_resolve(iterable)
|
|
||||||
|
return cls.resolve_connection(connection, args, iterable, max_limit=max_limit)
|
||||||
|
|
||||||
def wrap_resolve(self, parent_resolver):
|
def wrap_resolve(self, parent_resolver):
|
||||||
return partial(
|
return partial(
|
||||||
|
|
Loading…
Reference in New Issue
Block a user