Package: django-fancy-cache
Copyright Peter Bengtsson,mail@peterbe.com, 2013-2022License: BSDAbout django-fancy-cacheA Djangocache_pagedecorator on steroids.Unlike the stockdjango.views.decorators.cache.change_pagethis
decorator makes it possible to set akey_prefixthat is a
callable. This callable is passed the request and if it returnsNonethe page is not cached.Also, you can set another callable calledpost_process_response(which is passed the response and the request) which can do some
additional changes to the response before it’s set in cache.Lastly, you can setpost_process_response_always=Trueso that thepost_process_responsecallable is always called, even when the
response is coming from the cache.How to use itIn your Django views:fromfancy_cacheimportcache_pagefromdjango.utils.decoratorsimportmethod_decoratorfromdjango.views.genericimportTemplateView@cache_page(60*60)defmyview(request):returnrender(request,'page1.html')defprefixer(request):ifrequest.method!='GET':returnNoneifrequest.GET.get('no-cache'):returnNonereturn'myprefix'@cache_page(60*60,key_prefix=prefixer)defmyotherview(request):returnrender(request,'page2.html')defpost_processor(response,request):response.content+='<!-- this was post processed -->'returnresponse@cache_page(60*60,key_prefix=prefixer,post_process_response=post_processor)defyetanotherotherview(request):returnrender(request,'page3.html')classMyClassBasedView(TemplateView):template_name='page4.html'@method_decorator(cache_page(60*60))defget(self,request,*args,**kwargs):returnsuper().get(request,*args,**kwargs)Optional usesIf you want to you can havedjango-fancy-cacherecord every URL it
caches. This can be useful for things like invalidation or curious
statistical inspection.You can either switch this on on the decorator itself. Like this:fromfancy_cacheimportcache_page@cache_page(60*60,remember_all_urls=True)defmyview(request):returnrender(request,'page1.html')Or, more conveniently to apply it to all uses of thecache_pagedecorator you can set the default in your settings with:FANCY_REMEMBER_ALL_URLS=TrueNow, suppose you have the this option enabled. Now you can do things
like this:>>>fromfancy_cache.memoryimportfind_urls>>>list(find_urls(['/some/searchpath','/or/like/*/this.*']))>>># or, to get all:>>>list(find_urls([]))There is also another option to this and that is to purge (aka.
invalidate) the remembered URLs. You simply all thepurge=Trueoption like this:>>>fromfancy_cache.memoryimportfind_urls>>>list(find_urls([],purge=True))Note: Sincefind_urls()returns a generator, the purging won’t
happen unless you exhaust the generator. E.g. looping over it or
turning it into a list.If you are using Memcached, you must enable check-and-set to
remember all urls by enabling theFANCY_USE_MEMCACHED_CHECK_AND_SETflag and enablingcasin yourCACHESsettings:# in settings.pyFANCY_USE_MEMCACHED_CHECK_AND_SET=TrueCACHES={'default':{'BACKEND':'django.core.cache.backends.memcached.PyLibMCCache','LOCATION':'127.0.0.1:11211',# This OPTIONS setting enables Memcached check-and-set which is# required for remember_all_urls or FANCY_REMEMBER_ALL_URLS.'OPTIONS':{'behaviors':{'cas':True}}}}The second way to inspect all recorded URLs is to use thefancy-cachemanagement command. This is only available if you have
addedfancy_cacheto yourINSTALLED_APPSsetting. Now you can do
this:$ ./manage.py fancy-cache --help
$ ./manage.py fancy-cache
$ ./manage.py fancy-cache /some/searchpath /or/like/*/this.*
$ ./manage.py fancy-cache /some/place/* --purge
$ # or to purge them all!
$ ./manage.py fancy-cache --purgeNote, it will only print out URLs that if found (and purged, if
applicable).The third way to inspect the recorded URLs is to add this to your rooturls.py:url(r'fancy-cache',include('fancy_cache.urls')),Now, if you visithttp://localhost:8000/fancy-cacheyou get a table
listing every URL thatdjango-fancy-cachehas recorded.Optional uses (for the exceptionally curious)If you have enabledFANCY_REMEMBER_ALL_URLSyou can also enableFANCY_REMEMBER_STATS_ALL_URLSin your settings. What this does is
that it attempts to count the number of cache hits and cache misses
you have for each URL.This counting of hits and misses is configured to last “a long time”.
Possibly longer than you cache your view. So, over time you can expect
to have more than one miss because your view cache expires and it
starts over.You can see the stats whenever you use any of the ways described in
the section above. For example like this:>>>fromfancy_cache.memoryimportfind_urls>>>found=list(find_urls([]))[0]>>>found[0]'/some/page.html'>>>found[2]{'hits':1235,'misses':12}There is obviously a small additional performance cost of using theFANCY_REMEMBER_ALL_URLSand/orFANCY_REMEMBER_STATS_ALL_URLSin
your project so only use it if you don’t have any smarter way to
invalidate, for debugging or if you really want make it possible to
purge all cached responses when you run an upgrade of your site or
something.Running the test suiteThe simplest way is to simply run:$ pip install tox
$ toxOr to run it withouttoxyou can simply run:$ export PYTHONPATH=`pwd`
$ export DJANGO_SETTINGS_MODULE=fancy_tests.tests.settings
$ django-admin.py testChangelog1.3.1Fix a bug wherebyFANCY_COMPRESS_REMEMBERED_URLSsetting
raises a TypeError upon first implementation.1.3.0EnableFANCY_COMPRESS_REMEMBERED_URLSsetting to compressremembered_urlsdictionary whenFANCY_REMEMBER_ALL_URLSis True.Bugfix: use correct location forREMEMBERED_URLSwhen using Memcached.Add support for Python 3.11, Django 4.1 & 4.2Drop support for Python < 3.8, Django < 3.2, Django 4.01.2.1Bugfix: conflict between the DummyCache backend whenFANCY_USE_MEMCACHED_CHECK_AND_SETisTrue1.2.0Restructure the remembered_urls cache dict to clean up stale entriesUpdate FancyCacheMiddleware to match latest Django CacheMiddlware
(Also renames to FancyCacheMiddleware)Apply Memcached check-and-set to the delete_keys function
ifsettings.FANCY_USE_MEMCACHED_CHECK_AND_SET = TrueDrop support for Python <3.6Add support for Python 3.10 and Django 4.01.1.0If you use Memcached you can setsettings.FANCY_USE_MEMCACHED_CHECK_AND_SET = Trueso that you
can usecache._cache.caswhich only workd with Memcached1.0.0Drop support for Python <3.5 and Django <2.2.00.11.0Fix forparse_qscorrectly between Python 2 and Python 30.10.0Fix for keeping blank strings in query strings. #390.9.0Django 1.10 support0.8.2Remove deprecated way to define URL patterns and tests in python 3.50.8.1Ability to specify different cache backends to be usedhttps://github.com/peterbe/django-fancy-cache/pull/310.8.0Started keeping a Changelog