Skip to content

Instantly share code, notes, and snippets.

@diox
Created July 5, 2011 16:30
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save diox/1065196 to your computer and use it in GitHub Desktop.
Save diox/1065196 to your computer and use it in GitHub Desktop.
Django management command to clear johnny-cache cache :-)
import sys
import logging
from optparse import make_option
from django.core.management.base import BaseCommand, CommandError
class Command(BaseCommand):
help = ("Invalidates portions of the queryset cache based on the app names"
" or models provided as arguments to the command. If no arguments "
"are provided, nothing is done. To clear the entire queryset "
"cache, use the --all_models option.")
args = '[appname appname.ModelName ...]'
option_list = BaseCommand.option_list + (
make_option(
'--all-models', dest='all_models', action='store_true',
default=False, help='Invalidate the cache for all models.'
),
make_option(
'-e', '--exclude', dest='exclude', action='append', default=[],
help='App to exclude (use multiple --exclude to exclude multiple '
'apps).'
),
)
def handle(self, *app_labels, **options):
from django.core.cache import cache
from django.db.models import get_app, get_apps, get_models, get_model
from django.utils.datastructures import SortedDict
from johnny.cache import invalidate
from johnny.middleware import QueryCacheMiddleware
log = logging.getLogger('clear_johnny_cache')
# enable queryset cache
q = QueryCacheMiddleware()
all_models = options.get('all_models')
exclude = options.get('exclude')
excluded_apps = set(get_app(app_label) for app_label in exclude)
app_list = None
if all_models:
if len(app_labels):
# FIXME: warn user that specifying apps on the command line when
# using -all-models options has no impact
pass
app_list = SortedDict((app, None) for app in get_apps() if app not in excluded_apps)
elif not len(app_labels) == 0:
app_list = SortedDict()
for label in app_labels:
try:
app_label, model_label = label.split('.')
try:
app = get_app(app_label)
except ImproperlyConfigured:
raise CommandError("Unknown application: %s" % app_label)
model = get_model(app_label, model_label)
if model is None:
raise CommandError("Unknown model: %s.%s" % (app_label, model_label))
if app in app_list.keys():
if app_list[app] and model not in app_list[app]:
app_list[app].append(model)
else:
app_list[app] = [model]
except ValueError:
# This is just an app - no model qualifier
app_label = label
try:
app = get_app(app_label)
except ImproperlyConfigured:
raise CommandError("Unknown application: %s" % app_label)
app_list[app] = None
if app_list:
# Generate a list of models to be invalidated, and call the Johnny
# Cache invalidate command.
full_model_list = []
for app, model_list in app_list.items():
if model_list is None:
model_list = get_models(app)
if model_list:
full_model_list.extend(model_list)
log.info('Trying to clear cache for %d app(s), %d model(s) to invalidate' % (len(app_list), len(full_model_list)))
for model in full_model_list:
log.info('Invalidating cache for %s' % (model._meta.module_name))
invalidate(model)
log.info('Done invalidating')
else:
log.info('No model to invalidate')
@vdboor
Copy link

vdboor commented Dec 14, 2012

This is a nice feature to add to the johnney-cache app! :-D

@hobson
Copy link

hobson commented Aug 10, 2013

Awesome. --all_models in docstring should be --all-models

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment