mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-11 12:16:58 +03:00
Merge pull request #102 from graphql-python/features/source
Added source argument in Fields
This commit is contained in:
commit
141beb0364
|
@ -46,6 +46,9 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta, FieldsClassType)):
|
|||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def __getattr__(self, name):
|
||||
return self._root and getattr(self._root, name)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
signals.pre_init.send(self.__class__, args=args, kwargs=kwargs)
|
||||
self._root = kwargs.pop('_root', None)
|
||||
|
|
|
@ -4,6 +4,7 @@ from functools import wraps
|
|||
import six
|
||||
from graphql.core.type import GraphQLField, GraphQLInputObjectField
|
||||
|
||||
from ...utils import maybe_func
|
||||
from ..classtypes.base import FieldsClassType
|
||||
from ..classtypes.inputobjecttype import InputObjectType
|
||||
from ..classtypes.mutation import Mutation
|
||||
|
@ -18,7 +19,8 @@ class Field(NamedType, OrderedType):
|
|||
|
||||
def __init__(
|
||||
self, type, description=None, args=None, name=None, resolver=None,
|
||||
required=False, default=None, deprecation_reason=None, *args_list, **kwargs):
|
||||
source=None, required=False, default=None, deprecation_reason=None,
|
||||
*args_list, **kwargs):
|
||||
_creation_counter = kwargs.pop('_creation_counter', None)
|
||||
if isinstance(name, (Argument, ArgumentType)):
|
||||
kwargs['name'] = name
|
||||
|
@ -33,7 +35,12 @@ class Field(NamedType, OrderedType):
|
|||
args = OrderedDict(args or {}, **kwargs)
|
||||
self.arguments = ArgumentsGroup(*args_list, **args)
|
||||
self.object_type = None
|
||||
self.attname = None
|
||||
self.default_name = None
|
||||
self.resolver_fn = resolver
|
||||
self.source = source
|
||||
assert not (self.source and self.resolver_fn), ('You cannot have a source'
|
||||
' and a resolver at the same time')
|
||||
self.default = default
|
||||
|
||||
def contribute_to_class(self, cls, attname):
|
||||
|
@ -68,7 +75,8 @@ class Field(NamedType, OrderedType):
|
|||
return getattr(self.object_type, resolve_fn_name)
|
||||
|
||||
def default_getter(instance, args, info):
|
||||
return getattr(instance, self.attname, self.default)
|
||||
value = getattr(instance, self.source or self.attname, self.default)
|
||||
return maybe_func(value)
|
||||
return default_getter
|
||||
|
||||
def get_type(self, schema):
|
||||
|
@ -80,6 +88,8 @@ class Field(NamedType, OrderedType):
|
|||
return snake_case_args(resolver)
|
||||
|
||||
def internal_type(self, schema):
|
||||
if not self.object_type:
|
||||
raise Exception('The field is not mounted in any ClassType')
|
||||
resolver = self.resolver
|
||||
description = self.description
|
||||
arguments = self.arguments
|
||||
|
|
|
@ -180,3 +180,41 @@ def test_field_internal_type_deprecated():
|
|||
type = schema.T(field)
|
||||
assert isinstance(type, GraphQLField)
|
||||
assert type.deprecation_reason == deprecation_reason
|
||||
|
||||
|
||||
def test_field_resolve_object():
|
||||
class Root(object):
|
||||
att = True
|
||||
|
||||
@staticmethod
|
||||
def att_func():
|
||||
return True
|
||||
|
||||
field = Field(String(), description='My argument')
|
||||
field_func = Field(String(), description='My argument')
|
||||
|
||||
class Query(ObjectType):
|
||||
att = field
|
||||
att_func = field_func
|
||||
|
||||
assert field.resolver(Root, {}, None) is True
|
||||
assert field.resolver(Root, {}, None) is True
|
||||
|
||||
|
||||
def test_field_resolve_source_object():
|
||||
class Root(object):
|
||||
att_source = True
|
||||
|
||||
@staticmethod
|
||||
def att_func_source():
|
||||
return True
|
||||
|
||||
field = Field(String(), source='att_source', description='My argument')
|
||||
field_func = Field(String(), source='att_source', description='My argument')
|
||||
|
||||
class Query(ObjectType):
|
||||
att = field
|
||||
att_func = field_func
|
||||
|
||||
assert field.resolver(Root, {}, None) is True
|
||||
assert field.resolver(Root, {}, None) is True
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
from .str_converters import to_camel_case, to_snake_case
|
||||
from .proxy_snake_dict import ProxySnakeDict
|
||||
from .caching import cached_property, memoize
|
||||
from .maybe_func import maybe_func
|
||||
from .misc import enum_to_graphql_enum
|
||||
from .resolve_only_args import resolve_only_args
|
||||
from .lazylist import LazyList
|
||||
|
||||
|
||||
__all__ = ['to_camel_case', 'to_snake_case', 'ProxySnakeDict',
|
||||
'cached_property', 'memoize', 'enum_to_graphql_enum',
|
||||
'cached_property', 'memoize', 'maybe_func', 'enum_to_graphql_enum',
|
||||
'resolve_only_args', 'LazyList']
|
||||
|
|
7
graphene/utils/maybe_func.py
Normal file
7
graphene/utils/maybe_func.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
import inspect
|
||||
|
||||
|
||||
def maybe_func(f):
|
||||
if inspect.isfunction(f):
|
||||
return f()
|
||||
return f
|
9
graphene/utils/tests/test_maybe_func.py
Normal file
9
graphene/utils/tests/test_maybe_func.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from ..maybe_func import maybe_func
|
||||
|
||||
|
||||
def maybe_func_function():
|
||||
assert maybe_func(lambda: True) is True
|
||||
|
||||
|
||||
def maybe_func_value():
|
||||
assert maybe_func(True) is True
|
Loading…
Reference in New Issue
Block a user