from __future__ import unicode_literals | |
from django.db import models | |
class QuerySetClassManager(models.Manager): | |
""" | |
A mixin that refers to it's queryset_class attribute to create it. | |
""" | |
queryset_class = models.query.QuerySet | |
def get_queryset(self, *args, **kwargs): | |
return self.queryset_class(self.model, using=self._db, *args, **kwargs) | |
class QuerySetProxyManager(models.Manager): | |
""" | |
A mixin that fallbacks to queryset attributes when they are missing. | |
""" | |
def __getattr__(self, name): | |
try: | |
return getattr(self.__class__, name) | |
except AttributeError: | |
if name.startswith('__'): # Don't proxy reserved members | |
raise | |
return getattr(self.get_queryset(), name) | |
def queryset_manager_factory(queryset_class, bases=None, **attrs): | |
""" | |
A factory that creates a manager class proxying a query set subclass. | |
""" | |
# Try to figure out a decent manager name | |
name = queryset_class.__name__ | |
if 'QuerySet' in name: | |
name = str(name.replace('QuerySet', 'Manager')) | |
else: | |
name = str("%sManager" % name) | |
# Make sure the manager subclass both `QuerySetClassManager` and | |
# QuerySetProxyManager | |
if bases is None: | |
bases = (QuerySetClassManager, QuerySetProxyManager) | |
else: | |
if not any(issubclass(base, QuerySetClassManager) for base in bases): | |
bases = (QuerySetClassManager,) + bases | |
if not any(issubclass(base, QuerySetProxyManager) for base in bases): | |
bases = (QuerySetProxyManager,) + bases | |
# Added the appropriate attributes | |
attrs.update(queryset_class=queryset_class) | |
return type(name, bases, attrs) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment