Exemplo n.º 1
0
    def __init_subclass__(cls, **meta_options):
        _Meta = getattr(cls, "Meta", None)
        _meta_props = {}
        if _Meta:
            if isinstance(_Meta, dict):
                _meta_props = _Meta
            elif isclass(_Meta):
                _meta_props = props(_Meta)
            else:
                raise Exception(
                    "Meta have to be either a class or a dict. Received {}".format(
                        _Meta
                    )
                )
        options = dict(meta_options, **_meta_props)

        abstract = options.pop("abstract", False)
        if abstract:
            assert not options, (
                "Abstract types can only contain the abstract attribute. "
                "Received: abstract, {option_keys}"
            ).format(option_keys=", ".join(options.keys()))
        else:
            super_class = super(cls, cls)
            if hasattr(super_class, "__init_subclass_with_meta__"):
                super_class.__init_subclass_with_meta__(**options)
Exemplo n.º 2
0
 def __new__(cls, name, bases, attrs):
     input_class = attrs.pop('Input', None)
     if input_class:
         input_attrs = props(input_class)
         attrs['Input'] = type('Input',
                               (input_class, MutationRevisionMessage),
                               input_attrs)
         cls.Input = attrs['Input']
     return super().__new__(cls, name, bases, attrs)
 def _get_argument_fields(cls):
     input_class = getattr(cls, "Arguments", None)
     if not input_class:
         input_class = getattr(cls, "Input", None)
         if input_class:
             warn_deprecation((
                 "Please use {name}.Arguments instead of {name}.Input."
                 "Input is now only used in ClientMutationID.\nRead more: "
                 "https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#mutation-input"
             ).format(name=cls.__name__))
     arguments_props = {}
     if input_class:
         arguments_props = props(input_class)
     return arguments_props
Exemplo n.º 4
0
    def __init_subclass_with_meta__(cls,
                                    model=None,
                                    registry=None,
                                    optional_fields=[],
                                    only_fields=(),
                                    exclude_fields=None,
                                    **options):
        meta = SQLAlchemyMutationOptions(cls)
        meta.model = model

        model_inspect = sqlalchemyinspect(model)
        cls._model_inspect = model_inspect

        if not isinstance(exclude_fields, list):
            if exclude_fields:
                exclude_fields = list(exclude_fields)
            else:
                exclude_fields = []

        for primary_key_column in model_inspect.primary_key:
            if primary_key_column.autoincrement:
                exclude_fields.append(primary_key_column.name)

        for relationship in model_inspect.relationships:
            exclude_fields.append(relationship.key)

        for field in model_inspect.all_orm_descriptors:
            if type(field) == hybrid_property:
                exclude_fields.append(field.__name__)

        if not registry:
            registry = get_global_registry()

        fields = construct_fields(model, registry, only_fields, exclude_fields)

        for field_name in optional_fields:
            if field_name in fields:
                fields[field_name].kwargs["required"] = False

        argument_cls = getattr(cls, "Arguments", None)
        if argument_cls:
            fields.update(props(argument_cls))

        arguments = yank_fields_from_attrs(fields, _as=Argument)

        super(SQLAlchemyMutation,
              cls).__init_subclass_with_meta__(_meta=meta,
                                               arguments=arguments,
                                               **options)
Exemplo n.º 5
0
    def __new__(cls, name, bases, attrs):

        # Also ensure initialization is only performed for subclasses of
        # Mutation
        if not is_base_type(bases, DeleteMutationMeta):
            return type.__new__(cls, name, bases, attrs)

        cls = ObjectTypeMeta.__new__(cls, name, bases, attrs)
        input_class = getattr(cls, 'input_class', None)()

        field_args = props(input_class) if input_class else {}
        resolver = getattr(cls, 'mutate', None)
        assert resolver, 'All mutations must define a mutate method in it'
        resolver = get_unbound_function(resolver)
        cls.Field = partial(Field, cls, args=field_args, resolver=resolver)
        return cls
Exemplo n.º 6
0
    def __init_subclass_with_meta__(
        cls,
        interfaces: Iterable[Type[Interface]] = (),
        resolver: Callable = None,
        arguments: Dict[str, "Argument"] = None,
        _meta: Optional[ObjectTypeOptions] = None,
        **options: Any,
    ) -> None:
        if not _meta:
            _meta = MutationOptions(cls)

        fields = {}

        for interface in interfaces:
            assert issubclass(interface, Interface), (
                'All interfaces of {} must be a subclass of Interface. Received "{}".'
            ).format(cls.__name__, interface)
            fields.update(interface._meta.fields)

        fields = OrderedDict()
        for base in reversed(cls.__mro__):
            fields.update(yank_fields_from_attrs(base.__dict__, _as=Field))

        if not arguments:
            input_class = getattr(cls, "Arguments", None)

            if input_class:
                arguments = props(input_class)
            else:
                arguments = {}

        if not resolver:
            mutate = getattr(cls, "mutate", None)
            assert mutate, "All mutations must define a mutate method in it"
            resolver = get_unbound_function(mutate)

        if _meta.fields:
            _meta.fields.update(fields)
        else:
            _meta.fields = fields

        _meta.interfaces = interfaces
        _meta.resolver = resolver
        _meta.arguments = arguments

        super(SQLAlchemyMutation, cls).__init_subclass_with_meta__(_meta=_meta,
                                                                   **options)
Exemplo n.º 7
0
    def __init_subclass_with_meta__(cls,
                                    resolver=None,
                                    output=None,
                                    arguments=None,
                                    _meta=None,
                                    **options):
        if not _meta:
            _meta = SubscriptionOptions(cls)

        output = output or getattr(cls, 'Output', None)
        fields = {}
        if not output:
            # If output is defined, we don't need to get the fields
            fields = OrderedDict()
            for base in reversed(cls.__mro__):
                fields.update(yank_fields_from_attrs(base.__dict__, _as=Field))
            output = cls

        if not arguments:
            input_class = getattr(cls, 'Arguments', None)

            if input_class:
                arguments = props(input_class)
            else:
                arguments = {}

        if not resolver:
            assert hasattr(
                cls,
                'next'), 'All subscriptions must define a next method in it'
            resolver = get_unbound_function(getattr(cls, 'subscribe'))

        if _meta.fields:
            _meta.fields.update(fields)
        else:
            _meta.fields = fields

        _meta.output = output
        _meta.resolver = resolver
        _meta.arguments = arguments

        super(Subscription, cls).__init_subclass_with_meta__(_meta=_meta,
                                                             **options)
Exemplo n.º 8
0
    def __init_subclass_with_meta__(
        cls,
        serializer_class=None,
        queryset=None,
        only_fields=(),
        include_fields=(),
        exclude_fields=(),
        pagination=None,
        input_field_name=None,
        output_field_name=None,
        results_field_name=None,
        nested_fields=(),
        filter_fields=None,
        description="",
        filterset_class=None,
        **options,
    ):

        if not serializer_class:
            raise Exception(
                "serializer_class is required on all ModelSerializerType")

        model = serializer_class.Meta.model

        description = description or "ModelSerializerType for {} model".format(
            model.__name__)

        input_field_name = input_field_name or "new_{}".format(
            model._meta.model_name)
        output_field_name = output_field_name or model._meta.model_name

        input_class = getattr(cls, "Arguments", None)
        if not input_class:
            input_class = getattr(cls, "Input", None)
            if input_class:
                warn_deprecation((
                    "Please use {name}.Arguments instead of {name}.Input."
                    "Input is now only used in ClientMutationID.\nRead more: "
                    "https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#mutation-input"
                ).format(name=cls.__name__))
        if input_class:
            arguments = props(input_class)
        else:
            arguments = {}

        registry = get_global_registry()

        factory_kwargs = {
            "model": model,
            "only_fields": only_fields,
            "include_fields": include_fields,
            "exclude_fields": exclude_fields,
            "filter_fields": filter_fields,
            "pagination": pagination,
            "queryset": queryset,
            "nested_fields": nested_fields,
            "registry": registry,
            "skip_registry": False,
            "filterset_class": filterset_class,
            "results_field_name": results_field_name,
        }

        output_type = registry.get_type_for_model(model)

        if not output_type:
            output_type = factory_type("output", DjangoObjectType,
                                       **factory_kwargs)

        output_list_type = factory_type("list", DjangoListObjectType,
                                        **factory_kwargs)

        django_fields = OrderedDict({output_field_name: Field(output_type)})

        global_arguments = {}
        for operation in ("create", "delete", "update"):
            global_arguments.update({operation: OrderedDict()})

            if operation != "delete":
                input_type = registry.get_type_for_model(model,
                                                         for_input=operation)

                if not input_type:
                    # factory_kwargs.update({'skip_registry': True})
                    input_type = factory_type("input", DjangoInputObjectType,
                                              operation, **factory_kwargs)

                global_arguments[operation].update(
                    {input_field_name: Argument(input_type, required=True)})
            else:
                global_arguments[operation].update({
                    "id":
                    Argument(
                        ID,
                        required=True,
                        description="Django object unique identification field",
                    )
                })
            global_arguments[operation].update(arguments)

        _meta = DjangoSerializerOptions(cls)
        _meta.mutation_output = cls
        _meta.arguments = global_arguments
        _meta.fields = django_fields
        _meta.output_type = output_type
        _meta.output_list_type = output_list_type
        _meta.model = model
        _meta.queryset = queryset or model._default_manager
        _meta.serializer_class = serializer_class
        _meta.input_field_name = input_field_name
        _meta.output_field_name = output_field_name
        _meta.nested_fields = nested_fields

        super(DjangoSerializerType,
              cls).__init_subclass_with_meta__(_meta=_meta,
                                               description=description,
                                               **options)
Exemplo n.º 9
0
    def __init_subclass_with_meta__(cls, serializer_class=None, queryset=None, only_fields=(), exclude_fields=(),
                                    pagination=None, input_field_name=None, output_field_name=None,
                                    results_field_name=None, nested_fields=False, filter_fields=None, description='',
                                    **options):

        if not serializer_class:
            raise Exception('serializer_class is required on all ModelSerializerType')

        model = serializer_class.Meta.model

        description = description or 'ModelSerializerType for {} model'.format(model.__name__)

        input_field_name = input_field_name or 'new_{}'.format(model._meta.model_name)
        output_field_name = output_field_name or model._meta.model_name

        input_class = getattr(cls, 'Arguments', None)
        if not input_class:
            input_class = getattr(cls, 'Input', None)
            if input_class:
                warn_deprecation(("Please use {name}.Arguments instead of {name}.Input."
                                  "Input is now only used in ClientMutationID.\nRead more: "
                                  "https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#mutation-input").
                                 format(name=cls.__name__))
        if input_class:
            arguments = props(input_class)
        else:
            arguments = {}

        registry = get_global_registry()

        outputType = registry.get_type_for_model(model)

        if not outputType:
            outputType = object_type_factory(DjangoObjectType, new_model=model, new_only_fields=only_fields,
                                             new_exclude_fields=exclude_fields, new_filter_fields=filter_fields,
                                             new_registry=registry)

        outputListType = object_list_type_factory(DjangoListObjectType, model, new_only_fields=only_fields,
                                                  new_exclude_fields=exclude_fields, new_queryset=queryset,
                                                  new_results_field_name=results_field_name,
                                                  new_filter_fields=filter_fields, new_pagination=pagination)

        django_fields = OrderedDict({output_field_name: Field(outputType)})

        global_arguments = {}
        for operation in ('create', 'delete', 'update'):
            global_arguments.update({operation: OrderedDict()})

            if operation != 'delete':
                inputType = registry.get_type_for_model(model, for_input=operation)

                if not inputType:
                    inputType = input_object_type_factory(DjangoInputObjectType, new_model=model,
                                                          new_only_fields=only_fields, new_input_for=operation,
                                                          new_exclude_fields=exclude_fields, new_registry=registry,
                                                          new_skip_registry=True, new_nested_fields=nested_fields)

                global_arguments[operation].update({
                    input_field_name: Argument(inputType, required=True)
                })
            else:
                global_arguments[operation].update({
                    'id': Argument(ID, required=True, description='Django object unique identification field')
                })
            global_arguments[operation].update(arguments)

        _meta = DjangoSerializerOptions(cls)
        _meta.mutation_output = cls
        _meta.arguments = global_arguments
        _meta.fields = django_fields
        _meta.output_type = outputType
        _meta.output_list_type = outputListType
        _meta.model = model
        _meta.queryset = queryset or model._default_manager
        _meta.serializer_class = serializer_class
        _meta.input_field_name = input_field_name
        _meta.output_field_name = output_field_name

        super(DjangoSerializerType, cls).__init_subclass_with_meta__(_meta=_meta, description=description, **options)
Exemplo n.º 10
0
    def __init_subclass_with_meta__(cls, serializer_class=None, only_fields=(), exclude_fields=(),
                                    save_resolver=None, delete_resolver=None,
                                    input_field_name=None, output_field_name=None, description='',
                                    nested_fields=False, **options):

        if not serializer_class:
            raise Exception('serializer_class is required on all DjangoSerializerMutation')

        model = serializer_class.Meta.model

        description = description or 'SerializerMutation for {} model'.format(model.__name__)

        input_field_name = input_field_name or 'new_{}'.format(model._meta.model_name)
        output_field_name = output_field_name or model._meta.model_name

        input_class = getattr(cls, 'Arguments', None)
        if not input_class:
            input_class = getattr(cls, 'Input', None)
            if input_class:
                warn_deprecation(("Please use {name}.Arguments instead of {name}.Input."
                                  "Input is now only used in ClientMutationID.\nRead more: "
                                  "https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#mutation-input").
                                 format(name=cls.__name__))
        if input_class:
            arguments = props(input_class)
        else:
            arguments = {}

        registry = get_global_registry()

        factory_kwargs = {
            'model': model,
            'only_fields': only_fields,
            'exclude_fields': exclude_fields,
            'nested_fields': nested_fields,
            'registry': registry,
            'skip_registry': False
        }

        output_type = registry.get_type_for_model(model)

        if not output_type:
            output_type = factory_type('output', DjangoObjectType, **factory_kwargs)

        django_fields = OrderedDict({output_field_name: Field(output_type)})

        global_arguments = {}
        for operation in ('create', 'delete', 'update'):
            global_arguments.update({operation: OrderedDict()})

            if operation != 'delete':
                input_type = registry.get_type_for_model(model, for_input=operation)

                if not input_type:
                    factory_kwargs.update({'skip_registry': True})
                    input_type = factory_type('input', DjangoInputObjectType, operation, **factory_kwargs)

                global_arguments[operation].update({
                    input_field_name: Argument(input_type, required=True)
                })
            else:
                global_arguments[operation].update({
                    'id': Argument(ID, required=True, description='Django object unique identification field')
                })
            global_arguments[operation].update(arguments)

        if not save_resolver:
            save_mutation = getattr(cls, 'save_mutation', None)
            save_resolver = get_unbound_function(save_mutation) if save_mutation else None

        if not delete_resolver:
            delete_mutation = getattr(cls, 'delete_mutation', None)
            delete_resolver = get_unbound_function(delete_mutation) if delete_mutation else None

        assert (save_resolver or delete_resolver), \
            'All the SerializerMutations must define at least one of this class  methods: ' \
            '\'save_mutation\' or \'delete_mutation\''

        _meta = SerializerMutationOptions(cls)
        _meta.output = cls
        _meta.arguments = global_arguments
        _meta.fields = django_fields
        _meta.output_type = output_type
        _meta.save_resolver = save_resolver
        _meta.delete_resolver = delete_resolver
        _meta.model = model
        _meta.serializer_class = serializer_class
        _meta.input_field_name = input_field_name
        _meta.output_field_name = output_field_name

        super(DjangoSerializerMutation, cls).__init_subclass_with_meta__(_meta=_meta, description=description,
                                                                         **options)
Exemplo n.º 11
0
    def __init_subclass_with_meta__(cls,
                                    serializer_class=None,
                                    only_fields=(),
                                    exclude_fields=(),
                                    save_resolver=None,
                                    delete_resolver=None,
                                    input_field_name=None,
                                    output_field_name=None,
                                    description='',
                                    nested_fields=False,
                                    **options):

        if not serializer_class:
            raise Exception(
                'serializer_class is required on all DjangoSerializerMutation')

        model = serializer_class.Meta.model

        description = description or 'SerializerMutation for {} model'.format(
            model.__name__)

        input_field_name = input_field_name or 'new_{}'.format(
            model._meta.model_name)
        output_field_name = output_field_name or model._meta.model_name

        input_class = getattr(cls, 'Arguments', None)
        if not input_class:
            input_class = getattr(cls, 'Input', None)
            if input_class:
                warn_deprecation((
                    "Please use {name}.Arguments instead of {name}.Input."
                    "Input is now only used in ClientMutationID.\nRead more: "
                    "https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#mutation-input"
                ).format(name=cls.__name__))
        if input_class:
            arguments = props(input_class)
        else:
            arguments = {}

        registry = get_global_registry()

        factory_kwargs = {
            'model': model,
            'only_fields': only_fields,
            'exclude_fields': exclude_fields,
            'nested_fields': nested_fields,
            'registry': registry,
            'skip_registry': False
        }

        output_type = registry.get_type_for_model(model)

        if not output_type:
            output_type = factory_type('output', DjangoObjectType,
                                       **factory_kwargs)

        django_fields = OrderedDict({output_field_name: Field(output_type)})

        global_arguments = {}
        for operation in ('create', 'delete', 'update'):
            global_arguments.update({operation: OrderedDict()})

            if operation != 'delete':
                input_type = registry.get_type_for_model(model,
                                                         for_input=operation)

                if not input_type:
                    factory_kwargs.update({'skip_registry': True})
                    input_type = factory_type('input', DjangoInputObjectType,
                                              operation, **factory_kwargs)

                global_arguments[operation].update(
                    {input_field_name: Argument(input_type, required=True)})
            else:
                global_arguments[operation].update({
                    'id':
                    Argument(
                        ID,
                        required=True,
                        description='Django object unique identification field'
                    )
                })
            global_arguments[operation].update(arguments)

        if not save_resolver:
            save_mutation = getattr(cls, 'save_mutation', None)
            save_resolver = get_unbound_function(
                save_mutation) if save_mutation else None

        if not delete_resolver:
            delete_mutation = getattr(cls, 'delete_mutation', None)
            delete_resolver = get_unbound_function(
                delete_mutation) if delete_mutation else None

        assert (save_resolver or delete_resolver), \
            'All the SerializerMutations must define at least one of this class  methods: ' \
            '\'save_mutation\' or \'delete_mutation\''

        _meta = SerializerMutationOptions(cls)
        _meta.output = cls
        _meta.arguments = global_arguments
        _meta.fields = django_fields
        _meta.output_type = output_type
        _meta.save_resolver = save_resolver
        _meta.delete_resolver = delete_resolver
        _meta.model = model
        _meta.serializer_class = serializer_class
        _meta.input_field_name = input_field_name
        _meta.output_field_name = output_field_name

        super(DjangoSerializerMutation,
              cls).__init_subclass_with_meta__(_meta=_meta,
                                               description=description,
                                               **options)
Exemplo n.º 12
0
    def __new__(cls, name, bases, attrs):
        # Also ensure initialization is only performed for subclasses of
        # Mutation
        if not is_base_type(bases, ClientIDMutationMeta):
            return type.__new__(cls, name, bases, attrs)

        defaults = dict(
            name=name,
            description=attrs.pop('__doc__', None),
            interfaces=(),
            local_fields=None,
            permission_classes=(),
            throttle_classes=(),

            # for Django Model Permissions
            model=None,

            # for permissions
            method=None,  # 'CREATE', 'UPDATE', 'DELETE' only this 3 accepted
            form_class=None,

            lookup_field='pk',
            lookup_kwarg=None
        )

        options = Options(
            attrs.pop('Config', None),
            **defaults
        )

        if options.model is not None:
            assert is_valid_django_model(options.model), (
                'You need to pass a valid Django Model in {}.Meta, received "{}".'
            ).format(name, options.model)

        input_class = attrs.pop('Input', None)
        base_name = re.sub('Payload$', '', name)
        if 'client_mutation_id' not in attrs:
            attrs['client_mutation_id'] = String(name='clientMutationId')
        cls = ObjectTypeMeta.__new__(cls, '{}Payload'.format(base_name), bases, dict(attrs, _meta=options))
        mutate_and_get_payload = getattr(cls, 'mutate_and_get_payload', None)
        if cls.mutate and cls.mutate.__func__ == ClientIDMutation.mutate.__func__:
            assert mutate_and_get_payload, (
                "{}.mutate_and_get_payload method is required"
                " in a ClientIDMutation."
            ).format(name)
        input_attrs = {}
        bases = ()
        if not input_class:
            input_attrs = {}
        elif not issubclass(input_class, AbstractType):
            input_attrs = props(input_class)
        else:
            bases += (input_class, )
        input_attrs['client_mutation_id'] = String(name='clientMutationId')

        # If method is update and delete add id to input attrs
        if options.method is not None and options.method.upper() in ['UPDATE', 'DELETE']:
            input_attrs['id'] = String(name='id', required=True)

        cls.Input = type('{}Input'.format(base_name), bases + (InputObjectType,), input_attrs)
        cls.Field = partial(Field, cls, resolver=cls.mutate, input=Argument(cls.Input, required=True))

        return cls
Exemplo n.º 13
0
    def __init_subclass_with_meta__(cls, serializer_class=None, queryset=None, only_fields=(), exclude_fields=(),
                                    pagination=None, input_field_name=None, output_field_name=None,
                                    results_field_name=None, nested_fields=False, filter_fields=None, description='',
                                    filterset_class=None, **options):

        if not serializer_class:
            raise Exception('serializer_class is required on all ModelSerializerType')

        model = serializer_class.Meta.model

        description = description or 'ModelSerializerType for {} model'.format(model.__name__)

        input_field_name = input_field_name or 'new_{}'.format(model._meta.model_name)
        output_field_name = output_field_name or model._meta.model_name

        input_class = getattr(cls, 'Arguments', None)
        if not input_class:
            input_class = getattr(cls, 'Input', None)
            if input_class:
                warn_deprecation(("Please use {name}.Arguments instead of {name}.Input."
                                  "Input is now only used in ClientMutationID.\nRead more: "
                                  "https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#mutation-input").
                                 format(name=cls.__name__))
        if input_class:
            arguments = props(input_class)
        else:
            arguments = {}

        registry = get_global_registry()

        factory_kwargs = {
            'model': model,
            'only_fields': only_fields,
            'exclude_fields': exclude_fields,
            'filter_fields': filter_fields,
            'pagination': pagination,
            'queryset': queryset,
            'nested_fields': nested_fields,
            'registry': registry,
            'skip_registry': False,
            'filterset_class': filterset_class
        }

        output_type = registry.get_type_for_model(model)

        if not output_type:
            output_type = factory_type('output', DjangoObjectType, **factory_kwargs)

        output_list_type = factory_type('list', DjangoListObjectType, **factory_kwargs)

        django_fields = OrderedDict({output_field_name: Field(output_type)})

        global_arguments = {}
        for operation in ('create', 'delete', 'update'):
            global_arguments.update({operation: OrderedDict()})

            if operation != 'delete':
                input_type = registry.get_type_for_model(model, for_input=operation)

                if not input_type:
                    factory_kwargs.update({'skip_registry': True})
                    input_type = factory_type('input', DjangoInputObjectType, operation, **factory_kwargs)

                global_arguments[operation].update({
                    input_field_name: Argument(input_type, required=True)
                })
            else:
                global_arguments[operation].update({
                    'id': Argument(ID, required=True, description='Django object unique identification field')
                })
            global_arguments[operation].update(arguments)

        _meta = DjangoSerializerOptions(cls)
        _meta.mutation_output = cls
        _meta.arguments = global_arguments
        _meta.fields = django_fields
        _meta.output_type = output_type
        _meta.output_list_type = output_list_type
        _meta.model = model
        _meta.queryset = queryset or model._default_manager
        _meta.serializer_class = serializer_class
        _meta.input_field_name = input_field_name
        _meta.output_field_name = output_field_name

        super(DjangoSerializerType, cls).__init_subclass_with_meta__(_meta=_meta, description=description, **options)
    def __init_subclass_with_meta__(cls,
                                    model=None,
                                    name=None,
                                    description=None,
                                    interfaces=(),
                                    resolver=None,
                                    output=None,
                                    _meta=None,
                                    arguments=None,
                                    **options):

        assert model, "All Objects must define a Meta class with the model in it"
        assert issubclass(
            model, models.Model), "Model value must be a valid Django model"

        assert output, "Output Type must be defined in the Meta class"
        assert issubclass(
            output,
            ObjectType), "Outout Type must be a valid graphene object type"

        if not _meta:
            _meta = SubscriptionOptions(cls)

        output = output or getattr(cls, "Output", None)
        fields = {}

        for interface in interfaces:
            assert issubclass(
                interface, Interface
            ), f'All interfaces of {cls.__name__} must be a subclass of Interface. Received "{interface}".'
            fields.update(interface._meta.fields)

        if not arguments:
            input_class = getattr(cls, "Arguments", None)
            if input_class:
                arguments = props(input_class)
            else:
                arguments = {}

        if not resolver:
            resolver = cls._resolver

        assert hasattr(
            cls, "subscribe"
        ), "All subscribtions must define a subscribe method in it"

        post_save.connect(DjangoObjectSubscription.post_save_subscription,
                          sender=model)
        post_delete.connect(DjangoObjectSubscription.post_delete_subscription,
                            sender=model)

        if _meta.fields:
            _meta.fields.update(fields)
        else:
            _meta.fields = fields

        _meta.interfaces = interfaces
        _meta.output = output
        _meta.resolver = resolver
        _meta.arguments = arguments
        _meta.name = name
        _meta.model = model
        _meta.description = description

        super(DjangoObjectSubscription,
              cls).__init_subclass_with_meta__(_meta=_meta,
                                               name=name,
                                               description=description,
                                               **options)