mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-09 08:00:39 +03:00
Refactored GraphQL type generator
This commit is contained in:
parent
24cb8306c0
commit
1737089c6d
|
@ -3,7 +3,7 @@ from functools import partial
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from graphene import Field, Interface
|
from graphene import Field, Interface
|
||||||
from graphene.types.objecttype import ObjectType, ObjectTypeMeta, attrs_without_fields, GrapheneObjectType, get_interfaces
|
from graphene.types.objecttype import ObjectType, ObjectTypeMeta, attrs_without_fields, get_interfaces
|
||||||
from graphene.relay import Node
|
from graphene.relay import Node
|
||||||
from graphene.relay.node import NodeMeta
|
from graphene.relay.node import NodeMeta
|
||||||
from .converter import convert_django_field_with_choices
|
from .converter import convert_django_field_with_choices
|
||||||
|
@ -15,6 +15,8 @@ from graphene.utils.copy_fields import copy_fields
|
||||||
from graphene.utils.get_graphql_type import get_graphql_type
|
from graphene.utils.get_graphql_type import get_graphql_type
|
||||||
from graphene.utils.get_fields import get_fields
|
from graphene.utils.get_fields import get_fields
|
||||||
from graphene.utils.as_field import as_field
|
from graphene.utils.as_field import as_field
|
||||||
|
from graphene.generators import generate_objecttype
|
||||||
|
from graphene.generators.definitions import GrapheneObjectType
|
||||||
|
|
||||||
|
|
||||||
class DjangoObjectTypeMeta(ObjectTypeMeta):
|
class DjangoObjectTypeMeta(ObjectTypeMeta):
|
||||||
|
@ -81,14 +83,16 @@ class DjangoObjectTypeMeta(ObjectTypeMeta):
|
||||||
cls = super_new(cls, name, bases, dict(attrs, _meta=options))
|
cls = super_new(cls, name, bases, dict(attrs, _meta=options))
|
||||||
|
|
||||||
base_interfaces = tuple(b for b in bases if issubclass(b, Interface))
|
base_interfaces = tuple(b for b in bases if issubclass(b, Interface))
|
||||||
|
options.get_fields = partial(cls._construct_fields, fields, options)
|
||||||
|
options.get_interfaces = tuple(get_interfaces(interfaces + base_interfaces))
|
||||||
|
|
||||||
options.graphql_type = GrapheneObjectType(
|
options.graphql_type = GrapheneObjectType(
|
||||||
graphene_type=cls,
|
graphene_type=cls,
|
||||||
name=options.name or cls.__name__,
|
name=options.name or cls.__name__,
|
||||||
description=options.description or cls.__doc__,
|
description=options.description or cls.__doc__,
|
||||||
fields=partial(cls._construct_fields, fields, options),
|
fields=options.get_fields,
|
||||||
interfaces=tuple(get_interfaces(interfaces + base_interfaces))
|
interfaces=options.get_interfaces
|
||||||
)
|
)
|
||||||
options.get_fields = partial(cls._construct_fields, fields, options)
|
|
||||||
|
|
||||||
if issubclass(cls, DjangoObjectType):
|
if issubclass(cls, DjangoObjectType):
|
||||||
options.registry.register(cls)
|
options.registry.register(cls)
|
||||||
|
|
22
graphene/generators/__init__.py
Normal file
22
graphene/generators/__init__.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
from .definitions import GrapheneInterfaceType, GrapheneObjectType
|
||||||
|
|
||||||
|
|
||||||
|
def generate_interface(interface):
|
||||||
|
return GrapheneInterfaceType(
|
||||||
|
graphene_type=interface,
|
||||||
|
name=interface._meta.name or interface.__name__,
|
||||||
|
resolve_type=interface.resolve_type,
|
||||||
|
description=interface._meta.description or interface.__doc__,
|
||||||
|
fields=interface._meta.get_fields,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_objecttype(objecttype):
|
||||||
|
return GrapheneObjectType(
|
||||||
|
graphene_type=objecttype,
|
||||||
|
name=objecttype._meta.name or objecttype.__name__,
|
||||||
|
description=objecttype._meta.description or objecttype.__doc__,
|
||||||
|
fields=objecttype._meta.get_fields,
|
||||||
|
is_type_of=objecttype.is_type_of,
|
||||||
|
interfaces=objecttype._meta.get_interfaces
|
||||||
|
)
|
29
graphene/generators/definitions.py
Normal file
29
graphene/generators/definitions.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
from graphql import GraphQLObjectType, GraphQLInterfaceType
|
||||||
|
|
||||||
|
|
||||||
|
class GrapheneGraphQLType(object):
|
||||||
|
'''
|
||||||
|
A class for extending the base GraphQLType with the related
|
||||||
|
graphene_type
|
||||||
|
'''
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.graphene_type = kwargs.pop('graphene_type')
|
||||||
|
super(GrapheneGraphQLType, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class GrapheneInterfaceType(GrapheneGraphQLType, GraphQLInterfaceType):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class GrapheneObjectType(GrapheneGraphQLType, GraphQLObjectType):
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(GrapheneObjectType, self).__init__(*args, **kwargs)
|
||||||
|
self.check_interfaces()
|
||||||
|
|
||||||
|
def check_interfaces(self):
|
||||||
|
if not self._provided_interfaces:
|
||||||
|
return
|
||||||
|
for interface in self._provided_interfaces:
|
||||||
|
if isinstance(interface, GrapheneInterfaceType):
|
||||||
|
interface.graphene_type.implements(self.graphene_type)
|
|
@ -59,6 +59,4 @@ class ClientIDMutationMeta(MutationMeta):
|
||||||
|
|
||||||
|
|
||||||
class ClientIDMutation(six.with_metaclass(ClientIDMutationMeta, Mutation)):
|
class ClientIDMutation(six.with_metaclass(ClientIDMutationMeta, Mutation)):
|
||||||
|
pass
|
||||||
class Meta:
|
|
||||||
abstract = True
|
|
||||||
|
|
|
@ -1,5 +1 @@
|
||||||
class GrapheneGraphQLType(object):
|
from ..generators.definitions import GrapheneGraphQLType
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.graphene_type = kwargs.pop('graphene_type')
|
|
||||||
super(GrapheneGraphQLType, self).__init__(*args, **kwargs)
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
from .objecttype import Interface, GrapheneInterfaceType
|
from .objecttype import Interface
|
||||||
|
|
|
@ -1,32 +1,14 @@
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from graphql import GraphQLObjectType, GraphQLInterfaceType
|
|
||||||
|
|
||||||
from ..utils.copy_fields import copy_fields
|
from ..utils.copy_fields import copy_fields
|
||||||
from ..utils.get_fields import get_fields
|
from ..utils.get_fields import get_fields
|
||||||
from ..utils.is_base_type import is_base_type
|
from ..utils.is_base_type import is_base_type
|
||||||
from .definitions import GrapheneGraphQLType
|
|
||||||
from .field import Field
|
from .field import Field
|
||||||
from .options import Options
|
from .options import Options
|
||||||
|
|
||||||
|
|
||||||
class GrapheneInterfaceType(GrapheneGraphQLType, GraphQLInterfaceType):
|
from ..generators import generate_interface, generate_objecttype
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class GrapheneObjectType(GrapheneGraphQLType, GraphQLObjectType):
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(GrapheneObjectType, self).__init__(*args, **kwargs)
|
|
||||||
self.check_interfaces()
|
|
||||||
|
|
||||||
def check_interfaces(self):
|
|
||||||
if not self._provided_interfaces:
|
|
||||||
return
|
|
||||||
for interface in self._provided_interfaces:
|
|
||||||
if isinstance(interface, GrapheneInterfaceType):
|
|
||||||
interface.graphene_type.implements(self.graphene_type)
|
|
||||||
|
|
||||||
|
|
||||||
def get_interfaces(interfaces):
|
def get_interfaces(interfaces):
|
||||||
|
@ -47,14 +29,13 @@ def is_objecttype(bases):
|
||||||
def attrs_without_fields(attrs, fields):
|
def attrs_without_fields(attrs, fields):
|
||||||
return {k: v for k, v in attrs.items() if k not in fields}
|
return {k: v for k, v in attrs.items() if k not in fields}
|
||||||
|
|
||||||
|
|
||||||
# We inherit from InterfaceTypeMeta instead of type for being able
|
# We inherit from InterfaceTypeMeta instead of type for being able
|
||||||
# to have ObjectTypes extending Interfaces using Python syntax, like:
|
# to have ObjectTypes extending Interfaces using Python syntax, like:
|
||||||
# class MyObjectType(ObjectType, MyInterface)
|
# class MyObjectType(ObjectType, MyInterface)
|
||||||
class ObjectTypeMeta(type):
|
class ObjectTypeMeta(type):
|
||||||
|
|
||||||
def __new__(cls, name, bases, attrs):
|
def __new__(cls, name, bases, attrs):
|
||||||
super_new = type.__new__
|
|
||||||
|
|
||||||
# Also ensure initialization is only performed for subclasses of
|
# Also ensure initialization is only performed for subclasses of
|
||||||
# ObjectType,or Interfaces
|
# ObjectType,or Interfaces
|
||||||
if not is_base_type(bases, ObjectTypeMeta):
|
if not is_base_type(bases, ObjectTypeMeta):
|
||||||
|
@ -90,18 +71,12 @@ class ObjectTypeMeta(type):
|
||||||
|
|
||||||
if not options.graphql_type:
|
if not options.graphql_type:
|
||||||
fields = copy_fields(Field, fields, parent=cls)
|
fields = copy_fields(Field, fields, parent=cls)
|
||||||
options.graphql_type = GrapheneInterfaceType(
|
options.get_fields = lambda: fields
|
||||||
graphene_type=cls,
|
options.graphql_type = generate_interface(cls)
|
||||||
name=options.name or cls.__name__,
|
|
||||||
resolve_type=cls.resolve_type,
|
|
||||||
description=options.description or cls.__doc__,
|
|
||||||
fields=fields,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
assert not fields, "Can't mount Fields in an Interface with a defined graphql_type"
|
assert not fields, "Can't mount Fields in an Interface with a defined graphql_type"
|
||||||
fields = copy_fields(Field, options.graphql_type.get_fields(), parent=cls)
|
fields = copy_fields(Field, options.graphql_type.get_fields(), parent=cls)
|
||||||
|
options.get_fields = lambda: fields
|
||||||
options.get_fields = lambda: fields
|
|
||||||
|
|
||||||
for name, field in fields.items():
|
for name, field in fields.items():
|
||||||
setattr(cls, field.attname or name, field)
|
setattr(cls, field.attname or name, field)
|
||||||
|
@ -126,19 +101,14 @@ class ObjectTypeMeta(type):
|
||||||
if not options.graphql_type:
|
if not options.graphql_type:
|
||||||
fields = copy_fields(Field, fields, parent=cls)
|
fields = copy_fields(Field, fields, parent=cls)
|
||||||
base_interfaces = tuple(b for b in bases if issubclass(b, Interface))
|
base_interfaces = tuple(b for b in bases if issubclass(b, Interface))
|
||||||
options.graphql_type = GrapheneObjectType(
|
options.get_fields = lambda: fields
|
||||||
graphene_type=cls,
|
options.get_interfaces = tuple(get_interfaces(interfaces + base_interfaces))
|
||||||
name=options.name or cls.__name__,
|
options.graphql_type = generate_objecttype(cls)
|
||||||
description=options.description or cls.__doc__,
|
|
||||||
fields=fields,
|
|
||||||
is_type_of=cls.is_type_of,
|
|
||||||
interfaces=tuple(get_interfaces(interfaces + base_interfaces))
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
assert not fields, "Can't mount Fields in an ObjectType with a defined graphql_type"
|
assert not fields, "Can't mount Fields in an ObjectType with a defined graphql_type"
|
||||||
fields = copy_fields(Field, options.graphql_type.get_fields(), parent=cls)
|
fields = copy_fields(Field, options.graphql_type.get_fields(), parent=cls)
|
||||||
|
|
||||||
options.get_fields = lambda: fields
|
options.get_fields = lambda: fields
|
||||||
|
|
||||||
for name, field in fields.items():
|
for name, field in fields.items():
|
||||||
setattr(cls, field.attname or name, field)
|
setattr(cls, field.attname or name, field)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user