What happened in the Django 1.6 branch that affected how Manager metaclasses work?
Question: I have a little utility module, [django-
delegate](https://github.com/fish2000/django-delegate), that lets you define
methods on a QuerySet subclass and then “delegate” those method definitions to
a corresponding Manager subclass, by dint of a `@delegate` decoration.

It looks like this, if I can quote from my own
[README](https://github.com/fish2000/django-delegate/blob/master/README.rst):

    
    
    from delegate import DelegateManager, delegate
    
    class CustomQuerySet(models.query.QuerySet):
    
        @delegate
        def qs_method(self, some_value):
            return self.filter(some_param__icontains=some_value)
    
        def dont_delegate_me(self):
            return self.filter(some_other_param="something else")
    
    class CustomManager(DelegateManager):
        __queryset__ = CustomQuerySet
    
    class SomeModel(models.Model):
        objects = CustomManager()
    

… which that setup allows for method-chaining on the model’s manager
reference, without any runtime dispatch vaguery, like so†:

    
    
    >>> SomeModel.objects.custom_query().another_custom_query()
    

Behind-the-scenes, the module works by using a metaclass on the Manager
subclass, DelegateManager – and that worked without issue until Django turned
1.6. Now, when importing an app with models that use a DelegateManager, I get
one of these maddeningly esoteric metaclass-related showstopper TypeErrors:

    
    
    >>> from tika import models as tika
    Traceback (most recent call last):
      File "<input>", line 1, in <module>
      File "/Users/fish/Praxa/TESSAR/instance/tika/models.py", line 4, in <module>
        from delegate import DelegateManager, delegate
      File "/Users/fish/Praxa/TESSAR/local/lib/python2.7/site-packages/delegate/__init__.py", line 108, in <module>
        class DelegateManager(models.Manager):
      File "/Users/fish/Praxa/TESSAR/local/lib/python2.7/site-packages/delegate/__init__.py", line 105, in __new__
        cls, name, bases, attrs)
    TypeError: Error when calling the metaclass bases
        metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
    >>> 
    

**TL,DR:** what happened between versions 1.5 and 1.6 in Django’s Manager-
related plumbing that could cause this?

* * *

**†** – _N.B., I do understand I could solve this myself by either a) reading
through endless kLOCs of Django source diffs or b) accomplishing roughly the
same thing in one of the bajillion other ways that one could possibly approach
the notional idea django-delegate addresses; mainly I am interested in
whatever is causing this Manager metaclass situation, tho. Thank you, my
fellow Djangonauts_


Answer: In order to deprecate `get_query_set` in favor of `get_queryset`
([#15363](https://code.djangoproject.com/ticket/15363)) the
`django.db.models.manager.Manager` is now an instance of
`django.db.models.manager.RenameManagerMethods`, a subclass of
`django.utils.deprecation.RenameMethodsBase`.

Since `delegate.DelegateSupervisor` is not a (non-strict) subclass of
`django.db.models.manager.RenameManagerMethods` Python can't resolve the
correct `delegate.DelegateManager` metaclass.

To solve this issue you should make sure `delegate.DelegateSupervisor` is a
subclass of `type(django.db.models.manager.Manager)` and not `type`. This
should work for Django 1.5 and 1.6. I created a PR on your repository to fix
this issue.

By the way, you might want to take a look at the [Django 1.7 release
note](https://docs.djangoproject.com/en/dev/releases/1.7/#calling-custom-
queryset-methods-from-the-manager). A delegate alternative has been built-in
into Django.

