mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-21 14:02:51 +03:00
Improved query optimizer
This commit is contained in:
parent
c87ad41cf8
commit
867f0698f0
28
graphene/contrib/django/fetcher.py
Normal file
28
graphene/contrib/django/fetcher.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
from functools import wraps
|
||||||
|
from graphql.core.utils.get_field_def import get_field_def
|
||||||
|
from graphql.core.type.definition import GraphQLList, GraphQLNonNull
|
||||||
|
|
||||||
|
|
||||||
|
def get_fields(info):
|
||||||
|
field_asts = info.field_asts[0].selection_set.selections
|
||||||
|
only_args = []
|
||||||
|
_type = info.return_type
|
||||||
|
if isinstance(_type, (GraphQLList, GraphQLNonNull)):
|
||||||
|
_type = _type.of_type
|
||||||
|
|
||||||
|
for field in field_asts:
|
||||||
|
field_def = get_field_def(info.schema, _type, field)
|
||||||
|
f = field_def.resolver
|
||||||
|
fetch_field = getattr(f, 'django_fetch_field', None)
|
||||||
|
if not fetch_field:
|
||||||
|
continue
|
||||||
|
only_args.append(fetch_field.attname)
|
||||||
|
return only_args
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_only_required(f):
|
||||||
|
@wraps(f)
|
||||||
|
def wrapper(*args):
|
||||||
|
info = args[-1]
|
||||||
|
return f(*args).only(*get_fields(info))
|
||||||
|
return wrapper
|
|
@ -12,7 +12,7 @@ from .utils import get_type_for_model
|
||||||
class DjangoField(Field):
|
class DjangoField(Field):
|
||||||
def decorate_resolver(self, resolver):
|
def decorate_resolver(self, resolver):
|
||||||
f = super(DjangoField, self).decorate_resolver(resolver)
|
f = super(DjangoField, self).decorate_resolver(resolver)
|
||||||
setattr(f, 'django_fetch_field', self.field.name)
|
setattr(f, 'django_fetch_field', self.field)
|
||||||
return f
|
return f
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
|
@ -1,41 +1,16 @@
|
||||||
from functools import wraps
|
|
||||||
from graphql.core.utils.get_field_def import get_field_def
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
import graphene
|
import graphene
|
||||||
from graphene.contrib.django import DjangoObjectType
|
from graphene.contrib.django import DjangoObjectType
|
||||||
|
|
||||||
from graphql.core.type.definition import GraphQLList, GraphQLNonNull
|
|
||||||
|
|
||||||
|
|
||||||
from ..tests.models import Reporter
|
from ..tests.models import Reporter
|
||||||
from ..debug.plugin import DjangoDebugPlugin
|
from ..debug.plugin import DjangoDebugPlugin
|
||||||
|
from ..fetcher import fetch_only_required, get_fields
|
||||||
|
|
||||||
# from examples.starwars_django.models import Character
|
# from examples.starwars_django.models import Character
|
||||||
|
|
||||||
pytestmark = pytest.mark.django_db
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
def get_fields(info):
|
|
||||||
field_asts = info.field_asts[0].selection_set.selections
|
|
||||||
only_args = []
|
|
||||||
_type = info.return_type
|
|
||||||
if isinstance(_type, (GraphQLList, GraphQLNonNull)):
|
|
||||||
_type = _type.of_type
|
|
||||||
|
|
||||||
for field in field_asts:
|
|
||||||
field_def = get_field_def(info.schema, _type, field)
|
|
||||||
f = field_def.resolver
|
|
||||||
fetch_field = getattr(f, 'django_fetch_field', None)
|
|
||||||
if fetch_field:
|
|
||||||
only_args.append(fetch_field)
|
|
||||||
return only_args
|
|
||||||
|
|
||||||
def fetch_only_required(f):
|
|
||||||
@wraps(f)
|
|
||||||
def wrapper(*args):
|
|
||||||
info = args[-1]
|
|
||||||
return f(*args).only(*get_fields(info))
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
def test_should_query_well():
|
def test_should_query_well():
|
||||||
r1 = Reporter(last_name='ABA')
|
r1 = Reporter(last_name='ABA')
|
||||||
|
|
Loading…
Reference in New Issue
Block a user