graphene-django: Unable to subclass or emulate DjangoObjectType

Subclassing DjangoObjectType so as to customise it for use in derived objects in the schema causes the execution of:

assert is_valid_django_model(model)

which fails the assertion due toclass MyNewClass(DjangoObjectType): not having a meta class, as it meant to be a subclass of DjangoObjectType for reuse later on, not and thus does not have a Meta class of its own.

Its also not possible to emulate DjangoObjectType by copying DjangoObjectType, subclassing the new class from ObjectType, this gets past assert is_valid_django_model(model) but then things run into trouble in graphene_django.registry.Registry which runs:

assert issubclass(cls, DjangoObjectType), 'Only DjangoObjectTypes can be registered, received "{}"'.format(cls.__name__)

Which fails due to the explicit check for DjangoObjectType.

It shouldn’t require a fork of the entirety of graphene-django just to create a subclass of DjangoObjectType, either the Registry should be more flexible, or DjangoObjectType should be more flexible.

One option might be to use of Abstract Base Classes to enable a specific set of checks via https://docs.python.org/3/reference/datamodel.html?highlight=__subclass#class.__subclasscheck__

Another way would be to just drop these assertions and throw appropriate exceptions when we reach the situations they were designed to guard against. If we check that its a Django model to ensure that Meta exists, why not just throw a “Not A Django Model” exception when we try to do something later on that actually needs the Django model Meta information instead of asserting something way up the call stack that gets in the way of other things.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 5
  • Comments: 15 (1 by maintainers)

Most upvoted comments

I think this should probably stay open since it represents a rather significant limitation that deserves some kind of solution.

But who stops you from using

class Meta:
    abstract = True

in a subclass ?

This should probably be reopened unless it’s been fixed.

Ping on this, I’ve just hit this as a bit of a showstopper bug in our GraphQL implementation.

As mentioned by @techdragon this thing works for me:

class DjangoDynamicLoaderObjectType(DjangoObjectType):
    # ...
    class Meta:
        abstract = True
    
    #...

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@cobalamin thanks for this! I’ve just applied this technique on our codebase it it worked perfectly. Our previous hack was to use a dynamic base class which mypy then couldn’t inspect, so we’ve now got more idiomatic Python, simpler code, better linting and better typechecking!