Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching query results in django

Tags:

caching

django

I'm trying to find a way to cache the results of a query that won't change with frequency. For example, categories of products from an e-commerce (cellphones, TV, etc). I'm thinking of using the template fragment caching, but in this fragment, I will iterate over a list of these categories. This list is avaliable in any part of the site, so it's in my base.html file. Do I have always to send the list of categories when rendering the templates? Or is there a more dynamic way to do this, making the list always available in the template?

like image 280
Marcio Cruz Avatar asked Jan 08 '11 01:01

Marcio Cruz


2 Answers

Pop your cached query into Django's cache:

from django.core.cache import cache  cache.set('key', queryset) 

Then create a context processor to add the value of the cache to all templates:

# myproject/myapp/context_processors.py  from django.core.cache import cache  def cached_queries():     return {'cache', cache.get('key')} 

Then add your context processor in your Django settings file:

TEMPLATE_CONTEXT_PROCESSORS += (     'myproject.myapp.context_processors.cached_queries' ) 

Now you will be able to access the cache variable in all generic templates and all templates which have a requests context, which a template is given if this is done in the view:

return render_to_response('my_template.html',                           my_data_dictionary,                           context_instance=RequestContext(request)) 

When to Set the Cache

It depends on what is contained in the cache. However a common problem is that Django only really gets to execute Python whenever a page request is sent, and this is often not where you want to do this kind of work.

An alternative is to create a custom management command for a particular app. You can then either run this manually when necessary, or more commonly set this to run as a cron job.

To create a management command you must create a class decended from Command inside of a management/commands directory located inside of an app:

# myproject/myapp/management/commands/update_cache.py  from django.core.management.base import NoArgsCommand from django.core.cache import cache  class Command(NoArgsCommand):     help = 'Refreshes my cache'      def handle_noargs(self, **options):         cache.set('key', queryset) 

The name of this file is important as this will be the name of the command. In this case you can now call this on the command line:

python manage.py update_cache 
like image 170
Marcus Whybrow Avatar answered Sep 27 '22 23:09

Marcus Whybrow


You can also use johnny-cache for automatic caching of querysets. It will (by default) cache all querysets, but you can force it not to cache some.

like image 21
Matthew Schinckel Avatar answered Sep 28 '22 00:09

Matthew Schinckel