├── .gitignore ├── .travis.yml ├── MANIFEST.in ├── README.md ├── UNLICENSE ├── clear_cache.jpg ├── clear_cache ├── __init__.py ├── management │ ├── __init__.py │ └── commands │ │ ├── __init__.py │ │ └── clear_cache.py ├── models.py ├── tests.py └── views.py ├── manage.py ├── setup.py └── test_project ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore PyPI build stuff: 2 | dist 3 | *.egg-info 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.5" 4 | - "2.6" 5 | - "2.7" 6 | install: 7 | - python setup.py develop 8 | script: 9 | - python manage.py test clear_cache 10 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md clear_cache.jpg manage.py UNLICENSE 2 | recursive-exclude clear_cache *.pyc 3 | recursive-exclude test_project *.pyc 4 | recursive-include test_project 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # django-clear-cache 2 | 3 | 4 | ![I don't always clear my cache...](https://github.com/rdegges/django-clear-cache/raw/master/clear_cache.jpg) 5 | 6 | 7 | I often find myself in situations where I need to fully clear my website's 8 | cache (memcached or whatever). Often times this is required because: 9 | 10 | - I'm deploying new code and it will fail to run properly with my currently 11 | cached objects. 12 | - I need to purge invalid (or old) information. 13 | - A *million* other reasons. 14 | 15 | The standard way to clear your cache is to open up a management shell, eg: 16 | 17 | ``` bash 18 | $ python manage.py shell 19 | Python 2.7.3 (default, Apr 20 2012, 22:39:59) 20 | [GCC 4.6.3] on linux2 21 | Type "help", "copyright", "credits" or "license" for more information. 22 | (InteractiveConsole) 23 | >>> from django.core.cache import cache 24 | >>> cache.clear() 25 | ``` 26 | 27 | But obviously, this is annoying as I have to manually log into my production 28 | shell. 29 | 30 | ``django-clear-cache`` makes this process as easy as running a single 31 | management command. 32 | 33 | 34 | ## Install 35 | 36 | To install ``django-clear-cache``, simply run ``pip install django-clear-cache`` 37 | and you'll get the latest version installed automatically. 38 | 39 | Next, modify your Django ``settings.py`` file, and add ``clear_cache`` to your 40 | ``INSTALLED_APPS`` setting: 41 | 42 | ``` python 43 | INSTALLED_APPS = ( 44 | # ... 45 | 'clear_cache', 46 | ) 47 | ``` 48 | 49 | ## Usage 50 | 51 | To clear your cache, simply run the ``clear_cache`` management command: 52 | 53 | ``` bash 54 | $ python manage.py clear_cache 55 | Your cache has been cleared! 56 | ``` 57 | 58 | **NOTE**: This will only (obviously) work if you've got a cache configured (eg: 59 | memcached, local memory, etc.). If you have no idea what I'm talking about, 60 | read through the [official Django caching docs](https://docs.djangoproject.com/en/dev/topics/cache/?from=olddocs). 61 | 62 | 63 | ## Tests 64 | 65 | [![Build Status](https://secure.travis-ci.org/rdegges/django-clear-cache.png?branch=master)](http://travis-ci.org/rdegges/django-clear-cache) 66 | 67 | Want to run the tests? No problem: 68 | 69 | ``` bash 70 | $ git clone git://github.com/rdegges/django-clear-cache.git 71 | $ cd django-clear-cache 72 | $ python setup.py develop 73 | ... 74 | $ python manage.py test clear_cache 75 | Creating test database for alias 'default'... 76 | .Your cache has been cleared! 77 | .. 78 | ---------------------------------------------------------------------- 79 | Ran 3 tests in 1.007s 80 | 81 | OK 82 | Destroying test database for alias 'default'... 83 | ``` 84 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /clear_cache.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdegges/django-clear-cache/9251fd3730afb8ab3deaf5c2619889438fc760c4/clear_cache.jpg -------------------------------------------------------------------------------- /clear_cache/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdegges/django-clear-cache/9251fd3730afb8ab3deaf5c2619889438fc760c4/clear_cache/__init__.py -------------------------------------------------------------------------------- /clear_cache/management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdegges/django-clear-cache/9251fd3730afb8ab3deaf5c2619889438fc760c4/clear_cache/management/__init__.py -------------------------------------------------------------------------------- /clear_cache/management/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdegges/django-clear-cache/9251fd3730afb8ab3deaf5c2619889438fc760c4/clear_cache/management/commands/__init__.py -------------------------------------------------------------------------------- /clear_cache/management/commands/clear_cache.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.core.cache import cache 3 | from django.core.management.base import BaseCommand, CommandError 4 | 5 | 6 | class Command(BaseCommand): 7 | """A simple management command which clears the site-wide cache.""" 8 | help = 'Fully clear your site-wide cache.' 9 | 10 | def handle(self, *args, **kwargs): 11 | try: 12 | assert settings.CACHES 13 | cache.clear() 14 | self.stdout.write('Your cache has been cleared!\n') 15 | except AttributeError: 16 | raise CommandError('You have no cache configured!\n') 17 | -------------------------------------------------------------------------------- /clear_cache/models.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdegges/django-clear-cache/9251fd3730afb8ab3deaf5c2619889438fc760c4/clear_cache/models.py -------------------------------------------------------------------------------- /clear_cache/tests.py: -------------------------------------------------------------------------------- 1 | from time import sleep 2 | 3 | from django.conf import settings 4 | from django.core.cache import cache 5 | from django.core.management import call_command 6 | from django.test import TestCase 7 | 8 | 9 | class ClearCache(TestCase): 10 | 11 | def test_caching_works_as_expected(self): 12 | self.assertFalse(cache.get('woot')) 13 | cache.set('woot', 'woot', 1) 14 | self.assertTrue(cache.get('woot')) 15 | sleep(1) 16 | self.assertFalse(cache.get('woot')) 17 | 18 | def test_clears_cache(self): 19 | cache.set('omg', 'omg', 1) 20 | self.assertTrue(cache.get('omg')) 21 | call_command('clear_cache') 22 | self.assertFalse(cache.get('omg')) 23 | 24 | def test_fails_if_no_cache_is_configured(self): 25 | settings.CACHES = {} 26 | self.assertRaises(AssertionError, call_command, 'clear_cache') 27 | -------------------------------------------------------------------------------- /clear_cache/views.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdegges/django-clear-cache/9251fd3730afb8ab3deaf5c2619889438fc760c4/clear_cache/views.py -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_project.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from os.path import abspath, dirname, join, normpath 2 | 3 | from setuptools import setup 4 | 5 | 6 | setup( 7 | 8 | # Basic package information: 9 | name = 'django-clear-cache', 10 | version = '0.3', 11 | packages = ( 12 | 'clear_cache', 13 | 'clear_cache.management', 14 | 'clear_cache.management.commands' 15 | ), 16 | 17 | # Packaging options: 18 | zip_safe = False, 19 | include_package_data = True, 20 | 21 | # Package dependencies: 22 | install_requires = ['Django>=1.0'], 23 | 24 | # Metadata for PyPI: 25 | author = 'Randall Degges', 26 | author_email = 'rdegges@gmail.com', 27 | license = 'UNLICENSE', 28 | url = 'https://github.com/rdegges/django-clear-cache', 29 | keywords = 'django cache management memcached clear', 30 | description = 'A simple Django management command which clears your cache.', 31 | long_description = open(normpath(join(dirname(abspath(__file__)), 32 | 'README.md'))).read() 33 | 34 | ) 35 | -------------------------------------------------------------------------------- /test_project/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rdegges/django-clear-cache/9251fd3730afb8ab3deaf5c2619889438fc760c4/test_project/__init__.py -------------------------------------------------------------------------------- /test_project/settings.py: -------------------------------------------------------------------------------- 1 | # Django settings for test_project project. 2 | 3 | DEBUG = True 4 | TEMPLATE_DEBUG = DEBUG 5 | 6 | ADMINS = ( 7 | # ('Your Name', 'your_email@example.com'), 8 | ) 9 | 10 | MANAGERS = ADMINS 11 | 12 | DATABASES = { 13 | 'default': { 14 | 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. 15 | 'NAME': ':memory:', # Or path to database file if using sqlite3. 16 | 'USER': '', # Not used with sqlite3. 17 | 'PASSWORD': '', # Not used with sqlite3. 18 | 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. 19 | 'PORT': '', # Set to empty string for default. Not used with sqlite3. 20 | } 21 | } 22 | 23 | # Local time zone for this installation. Choices can be found here: 24 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name 25 | # although not all choices may be available on all operating systems. 26 | # On Unix systems, a value of None will cause Django to use the same 27 | # timezone as the operating system. 28 | # If running in a Windows environment this must be set to the same as your 29 | # system time zone. 30 | TIME_ZONE = 'America/Chicago' 31 | 32 | # Language code for this installation. All choices can be found here: 33 | # http://www.i18nguy.com/unicode/language-identifiers.html 34 | LANGUAGE_CODE = 'en-us' 35 | 36 | SITE_ID = 1 37 | 38 | # If you set this to False, Django will make some optimizations so as not 39 | # to load the internationalization machinery. 40 | USE_I18N = True 41 | 42 | # If you set this to False, Django will not format dates, numbers and 43 | # calendars according to the current locale. 44 | USE_L10N = True 45 | 46 | # If you set this to False, Django will not use timezone-aware datetimes. 47 | USE_TZ = True 48 | 49 | # Absolute filesystem path to the directory that will hold user-uploaded files. 50 | # Example: "/home/media/media.lawrence.com/media/" 51 | MEDIA_ROOT = '' 52 | 53 | # URL that handles the media served from MEDIA_ROOT. Make sure to use a 54 | # trailing slash. 55 | # Examples: "http://media.lawrence.com/media/", "http://example.com/media/" 56 | MEDIA_URL = '' 57 | 58 | # Absolute path to the directory static files should be collected to. 59 | # Don't put anything in this directory yourself; store your static files 60 | # in apps' "static/" subdirectories and in STATICFILES_DIRS. 61 | # Example: "/home/media/media.lawrence.com/static/" 62 | STATIC_ROOT = '' 63 | 64 | # URL prefix for static files. 65 | # Example: "http://media.lawrence.com/static/" 66 | STATIC_URL = '/static/' 67 | 68 | # Additional locations of static files 69 | STATICFILES_DIRS = ( 70 | # Put strings here, like "/home/html/static" or "C:/www/django/static". 71 | # Always use forward slashes, even on Windows. 72 | # Don't forget to use absolute paths, not relative paths. 73 | ) 74 | 75 | # List of finder classes that know how to find static files in 76 | # various locations. 77 | STATICFILES_FINDERS = ( 78 | 'django.contrib.staticfiles.finders.FileSystemFinder', 79 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 80 | # 'django.contrib.staticfiles.finders.DefaultStorageFinder', 81 | ) 82 | 83 | # Make this unique, and don't share it with anybody. 84 | SECRET_KEY = 'kgoqit(&apn#(s@jn0ari1pgtvi6_j#k94ut*=0y0v771qawfj' 85 | 86 | # List of callables that know how to import templates from various sources. 87 | TEMPLATE_LOADERS = ( 88 | 'django.template.loaders.filesystem.Loader', 89 | 'django.template.loaders.app_directories.Loader', 90 | # 'django.template.loaders.eggs.Loader', 91 | ) 92 | 93 | MIDDLEWARE_CLASSES = ( 94 | 'django.middleware.common.CommonMiddleware', 95 | 'django.contrib.sessions.middleware.SessionMiddleware', 96 | 'django.middleware.csrf.CsrfViewMiddleware', 97 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 98 | 'django.contrib.messages.middleware.MessageMiddleware', 99 | # Uncomment the next line for simple clickjacking protection: 100 | # 'django.middleware.clickjacking.XFrameOptionsMiddleware', 101 | ) 102 | 103 | ROOT_URLCONF = 'test_project.urls' 104 | 105 | # Python dotted path to the WSGI application used by Django's runserver. 106 | WSGI_APPLICATION = 'test_project.wsgi.application' 107 | 108 | TEMPLATE_DIRS = ( 109 | # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". 110 | # Always use forward slashes, even on Windows. 111 | # Don't forget to use absolute paths, not relative paths. 112 | ) 113 | 114 | INSTALLED_APPS = ( 115 | 'django.contrib.auth', 116 | 'django.contrib.contenttypes', 117 | 'django.contrib.sessions', 118 | 'django.contrib.sites', 119 | 'django.contrib.messages', 120 | 'django.contrib.staticfiles', 121 | # Uncomment the next line to enable the admin: 122 | # 'django.contrib.admin', 123 | # Uncomment the next line to enable admin documentation: 124 | # 'django.contrib.admindocs', 125 | 126 | 'clear_cache', 127 | ) 128 | 129 | # A sample logging configuration. The only tangible logging 130 | # performed by this configuration is to send an email to 131 | # the site admins on every HTTP 500 error when DEBUG=False. 132 | # See http://docs.djangoproject.com/en/dev/topics/logging for 133 | # more details on how to customize your logging configuration. 134 | LOGGING = { 135 | 'version': 1, 136 | 'disable_existing_loggers': False, 137 | 'filters': { 138 | 'require_debug_false': { 139 | '()': 'django.utils.log.RequireDebugFalse' 140 | } 141 | }, 142 | 'handlers': { 143 | 'mail_admins': { 144 | 'level': 'ERROR', 145 | 'filters': ['require_debug_false'], 146 | 'class': 'django.utils.log.AdminEmailHandler' 147 | } 148 | }, 149 | 'loggers': { 150 | 'django.request': { 151 | 'handlers': ['mail_admins'], 152 | 'level': 'ERROR', 153 | 'propagate': True, 154 | }, 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /test_project/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns, include, url 2 | 3 | # Uncomment the next two lines to enable the admin: 4 | # from django.contrib import admin 5 | # admin.autodiscover() 6 | 7 | urlpatterns = patterns('', 8 | # Examples: 9 | # url(r'^$', 'test_project.views.home', name='home'), 10 | # url(r'^test_project/', include('test_project.foo.urls')), 11 | 12 | # Uncomment the admin/doc line below to enable admin documentation: 13 | # url(r'^admin/doc/', include('django.contrib.admindocs.urls')), 14 | 15 | # Uncomment the next line to enable the admin: 16 | # url(r'^admin/', include(admin.site.urls)), 17 | ) 18 | -------------------------------------------------------------------------------- /test_project/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for test_project project. 3 | 4 | This module contains the WSGI application used by Django's development server 5 | and any production WSGI deployments. It should expose a module-level variable 6 | named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover 7 | this application via the ``WSGI_APPLICATION`` setting. 8 | 9 | Usually you will have the standard Django WSGI application here, but it also 10 | might make sense to replace the whole Django WSGI application with a custom one 11 | that later delegates to the Django one. For example, you could introduce WSGI 12 | middleware here, or combine a Django application with an application of another 13 | framework. 14 | 15 | """ 16 | import os 17 | 18 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_project.settings") 19 | 20 | # This application object is used by any WSGI server configured to use this 21 | # file. This includes Django's development server, if the WSGI_APPLICATION 22 | # setting points here. 23 | from django.core.wsgi import get_wsgi_application 24 | application = get_wsgi_application() 25 | 26 | # Apply WSGI middleware here. 27 | # from helloworld.wsgi import HelloWorldApplication 28 | # application = HelloWorldApplication(application) 29 | --------------------------------------------------------------------------------