Created
August 19, 2014 00:21
-
-
Save davesque/855553e11a811dc6ff9d to your computer and use it in GitHub Desktop.
Default queryset method call manager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import deque | |
from django.db import models | |
class MethodCalls(object): | |
""" | |
A mock object which logs chained method calls. | |
""" | |
def __init__(self): | |
self._calls = deque() | |
def __getattr__(self, name): | |
c = Call(self, name) | |
self._calls.append(c) | |
return c | |
def __iter__(self): | |
for c in self._calls: | |
yield tuple(c) | |
class Call(object): | |
""" | |
Used by `MethodCalls` objects internally to represent chained method calls. | |
""" | |
def __init__(self, calls_obj, method_name): | |
self._calls = calls_obj | |
self.method_name = method_name | |
def __call__(self, *method_args, **method_kwargs): | |
self.method_args = method_args | |
self.method_kwargs = method_kwargs | |
return self._calls | |
def __iter__(self): | |
yield self.method_name | |
yield self.method_args | |
yield self.method_kwargs | |
class DefaultQuerysetMethodCallsManager(models.Manager): | |
""" | |
A model manager class which allows specification of a sequence of | |
method calls to be applied by default to base querysets. | |
`DefaultQuerysetMethodCallsManager` instances expose a property | |
`default_queryset_method_calls` to which chained method calls can be | |
applied to indicate which methods should be called on base querysets. | |
For example:: | |
class Sandwich(models.Model): | |
bread = models.ForeignKey(Bread) | |
extras = models.ManyToManyField(Extra) | |
# Other field definitions... | |
objects = DefaultQuerysetMethodCallsManager() | |
objects.default_queryset_method_calls.filter( | |
bread__type='wheat', | |
).select_related( | |
'bread', | |
).prefetch_related( | |
'extras', | |
) | |
""" | |
def __init__(self, *args, **kwargs): | |
self.default_queryset_method_calls = MethodCalls() | |
super(DefaultQuerysetMethodCallsManager, self).__init__(*args, **kwargs) | |
def get_query_set(self, *args, **kwargs): | |
qs = super(DefaultQuerysetMethodCallsManager, self).get_query_set(*args, **kwargs) | |
for method_name, method_args, method_kwargs in self.default_queryset_method_calls: | |
qs = getattr(qs, method_name)(*method_args, **method_kwargs) | |
return qs |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment