mirror of
https://github.com/graphql-python/graphene-django.git
synced 2024-11-22 09:37:07 +03:00
Removed Meta inheritance in favor of __init_subclass_with_meta__
This commit is contained in:
parent
cec1a84480
commit
18db46e132
|
@ -3,11 +3,10 @@ from collections import OrderedDict
|
|||
import six
|
||||
|
||||
from django.utils.functional import SimpleLazyObject
|
||||
from graphene import Field, ObjectType
|
||||
from graphene.types.objecttype import ObjectTypeMeta
|
||||
from graphene.types.options import Options
|
||||
from graphene.types.utils import merge, yank_fields_from_attrs
|
||||
from graphene.utils.is_base_type import is_base_type
|
||||
from graphene import Field
|
||||
from graphene.relay import Connection, Node
|
||||
from graphene.types.objecttype import ObjectType, ObjectTypeOptions
|
||||
from graphene.types.utils import yank_fields_from_attrs
|
||||
|
||||
from .converter import convert_django_field_with_choices
|
||||
from .registry import Registry, get_global_registry
|
||||
|
@ -15,16 +14,14 @@ from .utils import (DJANGO_FILTER_INSTALLED, get_model_fields,
|
|||
is_valid_django_model)
|
||||
|
||||
|
||||
def construct_fields(options):
|
||||
_model_fields = get_model_fields(options.model)
|
||||
only_fields = options.only_fields
|
||||
exclude_fields = options.exclude_fields
|
||||
def construct_fields(model, registry, only_fields, exclude_fields):
|
||||
_model_fields = get_model_fields(model)
|
||||
|
||||
fields = OrderedDict()
|
||||
for name, field in _model_fields:
|
||||
is_not_in_only = only_fields and name not in options.only_fields
|
||||
is_already_created = name in options.fields
|
||||
is_excluded = name in exclude_fields or is_already_created
|
||||
is_not_in_only = only_fields and name not in only_fields
|
||||
# is_already_created = name in options.fields
|
||||
is_excluded = name in exclude_fields # or is_already_created
|
||||
# https://docs.djangoproject.com/en/1.10/ref/models/fields/#django.db.models.ForeignKey.related_query_name
|
||||
is_no_backref = str(name).endswith('+')
|
||||
if is_not_in_only or is_excluded or is_no_backref:
|
||||
|
@ -32,74 +29,67 @@ def construct_fields(options):
|
|||
# in there. Or when we exclude this field in exclude_fields.
|
||||
# Or when there is no back reference.
|
||||
continue
|
||||
converted = convert_django_field_with_choices(field, options.registry)
|
||||
converted = convert_django_field_with_choices(field, registry)
|
||||
fields[name] = converted
|
||||
|
||||
return fields
|
||||
|
||||
|
||||
class DjangoObjectTypeMeta(ObjectTypeMeta):
|
||||
class DjangoObjectTypeOptions(ObjectTypeOptions):
|
||||
model = None # type: Model
|
||||
registry = None # type: Registry
|
||||
connection = None # type: Type[Connection]
|
||||
|
||||
@staticmethod
|
||||
def __new__(cls, name, bases, attrs):
|
||||
# Also ensure initialization is only performed for subclasses of
|
||||
# DjangoObjectType
|
||||
if not is_base_type(bases, DjangoObjectTypeMeta):
|
||||
return type.__new__(cls, name, bases, attrs)
|
||||
filter_fields = ()
|
||||
|
||||
defaults = dict(
|
||||
name=name,
|
||||
description=attrs.pop('__doc__', None),
|
||||
model=None,
|
||||
local_fields=None,
|
||||
only_fields=(),
|
||||
exclude_fields=(),
|
||||
interfaces=(),
|
||||
skip_registry=False,
|
||||
registry=None
|
||||
)
|
||||
if DJANGO_FILTER_INSTALLED:
|
||||
# In case Django filter is available, then
|
||||
# we allow more attributes in Meta
|
||||
defaults.update(
|
||||
filter_fields=(),
|
||||
)
|
||||
|
||||
options = Options(
|
||||
attrs.pop('Meta', None),
|
||||
**defaults
|
||||
)
|
||||
if not options.registry:
|
||||
options.registry = get_global_registry()
|
||||
assert isinstance(options.registry, Registry), (
|
||||
'The attribute registry in {}.Meta needs to be an instance of '
|
||||
'Registry, received "{}".'
|
||||
).format(name, options.registry)
|
||||
assert is_valid_django_model(options.model), (
|
||||
class DjangoObjectType(ObjectType):
|
||||
@classmethod
|
||||
def __init_subclass_with_meta__(cls, model=None, registry=None, skip_registry=False,
|
||||
only_fields=(), exclude_fields=(), filter_fields=None, connection=None, use_connection=None, interfaces=(), **options):
|
||||
assert is_valid_django_model(model), (
|
||||
'You need to pass a valid Django Model in {}.Meta, received "{}".'
|
||||
).format(name, options.model)
|
||||
).format(cls.__name__, model)
|
||||
|
||||
cls = ObjectTypeMeta.__new__(cls, name, bases, dict(attrs, _meta=options))
|
||||
if not registry:
|
||||
registry = get_global_registry()
|
||||
|
||||
options.registry.register(cls)
|
||||
assert isinstance(registry, Registry), (
|
||||
'The attribute registry in {} needs to be an instance of '
|
||||
'Registry, received "{}".'
|
||||
).format(cls.__name__, registry)
|
||||
|
||||
options.django_fields = yank_fields_from_attrs(
|
||||
construct_fields(options),
|
||||
if not DJANGO_FILTER_INSTALLED and filter_fields:
|
||||
raise Exception("Can only set filter_fields if Django-Filter is installed")
|
||||
|
||||
django_fields = yank_fields_from_attrs(
|
||||
construct_fields(model, registry, only_fields, exclude_fields),
|
||||
_as=Field,
|
||||
)
|
||||
options.fields = merge(
|
||||
options.interface_fields,
|
||||
options.django_fields,
|
||||
options.base_fields,
|
||||
options.local_fields
|
||||
)
|
||||
|
||||
return cls
|
||||
if use_connection is None and interfaces:
|
||||
use_connection = any((issubclass(interface, Node) for interface in interfaces))
|
||||
|
||||
if use_connection and not connection:
|
||||
# We create the connection automatically
|
||||
connection = Connection.create_type('{}Connection'.format(cls.__name__), node=cls)
|
||||
|
||||
class DjangoObjectType(six.with_metaclass(DjangoObjectTypeMeta, ObjectType)):
|
||||
if connection is not None:
|
||||
assert issubclass(connection, Connection), "The connection must be a Connection. Received {}".format(connection.__name__)
|
||||
|
||||
def resolve_id(self, args, context, info):
|
||||
_meta = DjangoObjectTypeOptions(cls)
|
||||
_meta.model = model
|
||||
_meta.registry = registry
|
||||
_meta.filter_fields = filter_fields
|
||||
_meta.fields = django_fields
|
||||
_meta.connection = connection
|
||||
|
||||
super(DjangoObjectType, cls).__init_subclass_with_meta__(_meta=_meta, interfaces=interfaces, **options)
|
||||
|
||||
if not skip_registry:
|
||||
registry.register(cls)
|
||||
|
||||
def resolve_id(self):
|
||||
return self.pk
|
||||
|
||||
@classmethod
|
||||
|
|
Loading…
Reference in New Issue
Block a user