11

I am trying to cache query results on my django app. However, it seems that it is caching the whole app. I tried following logi:

def cacheView():
  result = cache.get('key')
  if result is None:
    result = Model.objects.get(id=1)
    cache.set('key', 'result')

I am calling this method when user logs in. However, if I try to logout after login, it keeps me on same page as if I am still logged in. I tried to follow the Django documentation on cache at http://docs.djangoproject.com/en/1.2/topics/cache/ but to no success.

Another thing I tried is that if I try to use the cache decorator just above the view as:

@cache_control(max_age=1000)
def cacheView():
 ...

it does it gives an error saying "response header not defined". I am new to django and sure that I missed something. Any idea?

2 Answers 2

12

RTFM :) Official Django Docs: Caching and QuerySets

Each QuerySet contains a cache, to minimize database access. (...)

and:

In a newly created QuerySet, the cache is empty. The first time a QuerySet is evaluated -- and, hence, a database query happens -- Django saves the query results in the QuerySet's cache and returns the results that have been explicitly requested (e.g., the next element, if the QuerySet is being iterated over). Subsequent evaluations of the QuerySet reuse the cached results.

Caching is done automagically in case of QuerySets (results of Queries).

EDIT: As for your code pasted in the question. If the key doesn't already exist in cache you have to create it with add() method but remember that it will expire by default after 30sec. If you want it to be kept longer you have to add timeout option to add()/set() method.

If you want to cache for whole your site (to ie. decorators as you used them), you need to add proper middleware to your MIDDLEWARE_CLASSES in settings.py (in this exact order, because middleware order matters, it is loaded one by one as you define them):

MIDDLEWARE_CLASSES = (
    # ...
    'django.middleware.cache.UpdateCacheMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.cache.FetchFromCacheMiddleware',
    # ...
)

If you don't have them, then you'll be receiving bad header errors every time you'll use caching-per-site capabilities.

Sign up to request clarification or add additional context in comments.

11 Comments

I definitely missed that on the manual. Now that I know it caches the queryset, my next question would be which cache method it uses. Because I wanted to store this in Memcache which I configured in my settings.py but not sure if django will take that method or will use database cache?
By default django is using local memory to store cache. If you've set other cache backend then django will use it.
One more question do U need to store this data for a very long time?
I've read all your question once again and I hope that I didn't misunderstand you. If you need to operate directly on cache with your object look here: docs.djangoproject.com/en/dev/topics/cache/… - I think that it will explain all your doubts. I mean caching whole view can be overkill - in some cases you would want to cache only some portion of data and for that you must use django.core.cache package. It's quite easy - you just write to it with set() method and you read from it via get() method. :)
@Anentropic - read my answer once again, try to unerstand what I'm explaining there. The problem is to get how cache is working and not how to use it in that case. Also question is about setting timeouts and invalidating the cache afterwards, which "poster" do not quite understand I think. Before caching anything there should be a proper strategy and a reason to do this. Also the QuerySet object has nothing to do with cache.set()/cache.add(). And btw question was edited by the author also after my response - look at the comments..
|
1

From your example it's not clear why the logout would fail, but it shouldn't be anything to do with caching a model (unless you're caching the User model and using the cached user for authentication instead of request.user?)

It's fine to use cache.get and cache.set the way you are (set will create a new key if it doesn't exist).

Caching queries can be difficult as you need to take care of invalidating the cache when data changes so as not to serve stale results.

Have a look at these query-caching libraries for Django which aim to make things easier:

http://jbalogh.me/2010/02/09/cache-machine/

http://packages.python.org/johnny-cache/queryset_cache.html

1 Comment

you don't need additional libs as long as you know what are you doing and what you want to accomplish - there is nothing easier (and more complicated at the same time) than caching.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.