mirror of
				https://github.com/graphql-python/graphene-django.git
				synced 2025-11-04 18:08:01 +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
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.utils.functional import SimpleLazyObject
 | 
					from django.utils.functional import SimpleLazyObject
 | 
				
			||||||
from graphene import Field, ObjectType
 | 
					from graphene import Field
 | 
				
			||||||
from graphene.types.objecttype import ObjectTypeMeta
 | 
					from graphene.relay import Connection, Node
 | 
				
			||||||
from graphene.types.options import Options
 | 
					from graphene.types.objecttype import ObjectType, ObjectTypeOptions
 | 
				
			||||||
from graphene.types.utils import merge, yank_fields_from_attrs
 | 
					from graphene.types.utils import yank_fields_from_attrs
 | 
				
			||||||
from graphene.utils.is_base_type import is_base_type
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .converter import convert_django_field_with_choices
 | 
					from .converter import convert_django_field_with_choices
 | 
				
			||||||
from .registry import Registry, get_global_registry
 | 
					from .registry import Registry, get_global_registry
 | 
				
			||||||
| 
						 | 
					@ -15,16 +14,14 @@ from .utils import (DJANGO_FILTER_INSTALLED, get_model_fields,
 | 
				
			||||||
                    is_valid_django_model)
 | 
					                    is_valid_django_model)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def construct_fields(options):
 | 
					def construct_fields(model, registry, only_fields, exclude_fields):
 | 
				
			||||||
    _model_fields = get_model_fields(options.model)
 | 
					    _model_fields = get_model_fields(model)
 | 
				
			||||||
    only_fields = options.only_fields
 | 
					 | 
				
			||||||
    exclude_fields = options.exclude_fields
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fields = OrderedDict()
 | 
					    fields = OrderedDict()
 | 
				
			||||||
    for name, field in _model_fields:
 | 
					    for name, field in _model_fields:
 | 
				
			||||||
        is_not_in_only = only_fields and name not in options.only_fields
 | 
					        is_not_in_only = only_fields and name not in only_fields
 | 
				
			||||||
        is_already_created = name in options.fields
 | 
					        # is_already_created = name in options.fields
 | 
				
			||||||
        is_excluded = name in exclude_fields or is_already_created
 | 
					        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
 | 
					        # https://docs.djangoproject.com/en/1.10/ref/models/fields/#django.db.models.ForeignKey.related_query_name
 | 
				
			||||||
        is_no_backref = str(name).endswith('+')
 | 
					        is_no_backref = str(name).endswith('+')
 | 
				
			||||||
        if is_not_in_only or is_excluded or is_no_backref:
 | 
					        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.
 | 
					            # in there. Or when we exclude this field in exclude_fields.
 | 
				
			||||||
            # Or when there is no back reference.
 | 
					            # Or when there is no back reference.
 | 
				
			||||||
            continue
 | 
					            continue
 | 
				
			||||||
        converted = convert_django_field_with_choices(field, options.registry)
 | 
					        converted = convert_django_field_with_choices(field, registry)
 | 
				
			||||||
        fields[name] = converted
 | 
					        fields[name] = converted
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return fields
 | 
					    return fields
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DjangoObjectTypeMeta(ObjectTypeMeta):
 | 
					class DjangoObjectTypeOptions(ObjectTypeOptions):
 | 
				
			||||||
 | 
					    model = None  # type: Model
 | 
				
			||||||
 | 
					    registry = None  # type: Registry
 | 
				
			||||||
 | 
					    connection = None  # type: Type[Connection]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    filter_fields = ()
 | 
				
			||||||
    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)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        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(
 | 
					class DjangoObjectType(ObjectType):
 | 
				
			||||||
            attrs.pop('Meta', None),
 | 
					    @classmethod
 | 
				
			||||||
            **defaults
 | 
					    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):
 | 
				
			||||||
        if not options.registry:
 | 
					        assert is_valid_django_model(model), (
 | 
				
			||||||
            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), (
 | 
					 | 
				
			||||||
            'You need to pass a valid Django Model in {}.Meta, received "{}".'
 | 
					            '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(
 | 
					        if not DJANGO_FILTER_INSTALLED and filter_fields:
 | 
				
			||||||
            construct_fields(options),
 | 
					            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,
 | 
					            _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
 | 
					        return self.pk
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user