Skip to content

Instantly share code, notes, and snippets.

@charettes
Created June 20, 2013 13:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save charettes/5822558 to your computer and use it in GitHub Desktop.
Save charettes/5822558 to your computer and use it in GitHub Desktop.
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