I have many heavy views which run slowly when accessed at same time in multiple threads. I make this decorator to allow run only one view at the time and cache returned result. Other threads will wait to complete first thread and use response from the cache if executed thread put it to cache.
Also I take idea of MintCache to refresh staled cache and return cached (stale) response while response refreshed in the cache.
Usage:
@single_cacheable(cache_timeout=60,
stale_timeout=30,
key_template='my_heavy_view-{arg1}-{arg2}')
def heavy_view(request, arg1, arg2):
response = HttpResponse()
... your code here
# cache timeout may be set from inside of view
response._cache_timeout = cache_time
return responce
The "key_template" is a template for cache key. Some my views have additinal parameter "cache_time" which set from parent page and request.path is different for these pages but they need to be cached not depending of this parameter.
Variable "key_template" in the example used named agrument, if you have no named paramaters you need to use 'my_heavy_view-{1}-{2}-{...}' where {1},{2}, {...} arguments of view.
The line with setting "key" variable may be changed to:
key = "sc_"+request.get_full_path()
if you need to take full URL path as cache key.
An example of how to select the "default" database based on the request URL instead of the model. The basic idea is that the middleware `process_view` (or `process_request`) function sets some context from the URL into thread local storage, and `process_response` deletes it. In between, any database operation will call the router, which checks for this context and returns an appropriate database alias.
In this snippet, it's assumed that any view in the system with a `cfg` keyword argument passed to it from the urlconf may be routed to a separate database. Take this urlconf for example:
`url( r'^(?P<cfg>\w+)/account/$', 'views.account' )`
The middleware and router will select a database whose alias is `<cfg>`, or "default" if none is listed in `settings.DATABASES`, all completely transparent to the view itself.
- multidb database router url
http://github.com/coleifer/django-generic-aggregation
http://charlesleifer.com/blog/generating-aggregate-data-across-generic-relations/
Generate and calculate aggregations across generic foreign keys.
>>> from misc import generic_annotate, generic_aggregate
>>> from blog.models import Entry
>>> from tagging.models import TaggedItem
>>> from django.db.models import Count
>>> qs = generic_annotate(Entry.objects.all(), TaggedItem.object, 'id', Count)
>>> qs[0].score
5L
>>> qs[1].score
4L
>>> qs[1].tags
u'databases django many-to-many python'
>>> generic_aggregate(Entry.objects.all(), TaggedItem.object, 'id', Count)
106L # total number of times entries were tagged