mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 12:44:15 +03:00
Added ability to skip fields in runtime
This commit is contained in:
parent
3f9b94b73f
commit
25eca8776a
|
@ -65,14 +65,18 @@ class DjangoModelField(Field):
|
||||||
@memoize
|
@memoize
|
||||||
def internal_type(self, schema):
|
def internal_type(self, schema):
|
||||||
_type = self.get_object_type(schema)
|
_type = self.get_object_type(schema)
|
||||||
return _type and _type.internal_type(schema)
|
if not _type and self.object_type._meta.only_fields:
|
||||||
|
raise Exception(
|
||||||
|
"Model %r is not accessible by the schema. "
|
||||||
|
"You can either register the type manually "
|
||||||
|
"using @schema.register. "
|
||||||
|
"Or disable the field %s in %s" % (
|
||||||
|
self.model,
|
||||||
|
self.field_name,
|
||||||
|
self.object_type
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return _type and _type.internal_type(schema) or Field.SKIP
|
||||||
|
|
||||||
def get_object_type(self, schema):
|
def get_object_type(self, schema):
|
||||||
_type = get_type_for_model(schema, self.model)
|
return get_type_for_model(schema, self.model)
|
||||||
if not _type and self.object_type._meta.only_fields:
|
|
||||||
# We will only raise the exception if the related field is
|
|
||||||
# specified in only_fields
|
|
||||||
raise Exception("Field %s (%s) model not mapped in current schema" % (
|
|
||||||
self, self.model._meta.object_name))
|
|
||||||
|
|
||||||
return _type
|
|
||||||
|
|
|
@ -46,4 +46,7 @@ class DjangoInterface(six.with_metaclass(DjangoObjectTypeMeta, BaseObjectType)):
|
||||||
|
|
||||||
|
|
||||||
class DjangoNode(BaseNode, DjangoInterface):
|
class DjangoNode(BaseNode, DjangoInterface):
|
||||||
pass
|
@classmethod
|
||||||
|
def get_node(cls, id):
|
||||||
|
instance = cls._meta.model.objects.filter(id=id).first()
|
||||||
|
return cls(instance)
|
||||||
|
|
|
@ -12,9 +12,11 @@ from graphql.core.type import (
|
||||||
)
|
)
|
||||||
from graphene.utils import memoize, to_camel_case
|
from graphene.utils import memoize, to_camel_case
|
||||||
from graphene.core.types import BaseObjectType
|
from graphene.core.types import BaseObjectType
|
||||||
|
from graphene.core.scalars import GraphQLSkipField
|
||||||
|
|
||||||
|
|
||||||
class Field(object):
|
class Field(object):
|
||||||
|
SKIP = GraphQLSkipField
|
||||||
|
|
||||||
def __init__(self, field_type, name=None, resolve=None, null=True, args=None, description='', **extra_args):
|
def __init__(self, field_type, name=None, resolve=None, null=True, args=None, description='', **extra_args):
|
||||||
self.field_type = field_type
|
self.field_type = field_type
|
||||||
|
@ -95,7 +97,8 @@ class Field(object):
|
||||||
))
|
))
|
||||||
|
|
||||||
internal_type = self.internal_type(schema)
|
internal_type = self.internal_type(schema)
|
||||||
|
if not internal_type:
|
||||||
|
raise Exception("Internal type for field %s is None" % self)
|
||||||
return GraphQLField(
|
return GraphQLField(
|
||||||
internal_type,
|
internal_type,
|
||||||
description=self.description,
|
description=self.description,
|
||||||
|
@ -111,7 +114,7 @@ class Field(object):
|
||||||
"""
|
"""
|
||||||
Displays the module, class and name of the field.
|
Displays the module, class and name of the field.
|
||||||
"""
|
"""
|
||||||
path = '%s.%s' % (self.__class__.__module__, self.__class__.__name__)
|
path = '%r.%s' % (self.object_type, self.__class__.__name__)
|
||||||
name = getattr(self, 'field_name', None)
|
name = getattr(self, 'field_name', None)
|
||||||
if name is not None:
|
if name is not None:
|
||||||
return '<%s: %s>' % (path, name)
|
return '<%s: %s>' % (path, name)
|
||||||
|
|
10
graphene/core/scalars.py
Normal file
10
graphene/core/scalars.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from graphql.core.type.definition import GraphQLScalarType
|
||||||
|
|
||||||
|
|
||||||
|
def skip(value):
|
||||||
|
return None
|
||||||
|
|
||||||
|
GraphQLSkipField = GraphQLScalarType(name='SkipField',
|
||||||
|
serialize=skip,
|
||||||
|
parse_value=skip,
|
||||||
|
parse_literal=skip)
|
|
@ -45,6 +45,10 @@ class Schema(object):
|
||||||
def associate_internal_type(self, internal_type, object_type):
|
def associate_internal_type(self, internal_type, object_type):
|
||||||
self._internal_types[internal_type.name] = object_type
|
self._internal_types[internal_type.name] = object_type
|
||||||
|
|
||||||
|
def register(self, object_type):
|
||||||
|
self._internal_types[object_type._meta.type_name] = object_type
|
||||||
|
return object_type
|
||||||
|
|
||||||
def get_type(self, type_name):
|
def get_type(self, type_name):
|
||||||
# print 'get_type'
|
# print 'get_type'
|
||||||
# _type = self.schema.get_type(type_name)
|
# _type = self.schema.get_type(type_name)
|
||||||
|
|
|
@ -49,7 +49,7 @@ class ObjectTypeMeta(type):
|
||||||
new_class.add_extra_fields()
|
new_class.add_extra_fields()
|
||||||
|
|
||||||
new_fields = new_class._meta.local_fields
|
new_fields = new_class._meta.local_fields
|
||||||
field_names = {f.name for f in new_fields}
|
field_names = {f.name:f for f in new_fields}
|
||||||
|
|
||||||
for base in parents:
|
for base in parents:
|
||||||
original_base = base
|
original_base = base
|
||||||
|
@ -65,7 +65,7 @@ class ObjectTypeMeta(type):
|
||||||
# on the base classes (we cannot handle shadowed fields at the
|
# on the base classes (we cannot handle shadowed fields at the
|
||||||
# moment).
|
# moment).
|
||||||
for field in parent_fields:
|
for field in parent_fields:
|
||||||
if field.name in field_names:
|
if field.name in field_names and field.__class__ != field_names[field].__class__:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
'Local field %r in class %r clashes '
|
'Local field %r in class %r clashes '
|
||||||
'with field of similar name from '
|
'with field of similar name from '
|
||||||
|
|
|
@ -19,6 +19,8 @@ def get_node(schema, globalId, *args):
|
||||||
resolvedGlobalId = fromGlobalId(globalId)
|
resolvedGlobalId = fromGlobalId(globalId)
|
||||||
_type, _id = resolvedGlobalId.type, resolvedGlobalId.id
|
_type, _id = resolvedGlobalId.type, resolvedGlobalId.id
|
||||||
object_type = schema.get_type(_type)
|
object_type = schema.get_type(_type)
|
||||||
|
if not object_type or not issubclass(object_type, BaseNode):
|
||||||
|
raise Exception("The type %s is not a Node" % _type)
|
||||||
return object_type.get_node(_id)
|
return object_type.get_node(_id)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,6 @@ def test_should_raise_if_model_is_invalid():
|
||||||
result = schema.execute(query)
|
result = schema.execute(query)
|
||||||
assert not result.errors
|
assert not result.errors
|
||||||
|
|
||||||
assert 'articles (Article) model not mapped in current schema' in str(
|
|
||||||
excinfo.value)
|
|
||||||
|
|
||||||
|
|
||||||
def test_should_map_fields_correctly():
|
def test_should_map_fields_correctly():
|
||||||
class ReporterType2(DjangoObjectType):
|
class ReporterType2(DjangoObjectType):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user