Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django pre-calculate and cache a view

Tags:

python

django

This might be a python question. It is a noobish one to be sure.

A client requests a calculation-intensive page [page-1] and will ultimately request a second calculation-intensive page [page-2], which can be calculated the instance the request for page-1 is known. I don't want to calculate each set of data before serving page-1 because it will significantly slow down the performance of the initial response.

I do want to calculate the value for page-2 while the client reads page-1. The client also might click on some buttons which cause a response that provides a different view of page-1 data, but don't necessitate an intensive calculating. Eventually but not necessarily immediately, the client will ask for page-2 and I want to be able to response with a pre-rendered response.

How do I do this?

like image 986
Cole Avatar asked Jan 16 '13 03:01

Cole


People also ask

What is pre site caching in Django?

CACHE_MIDDLEWARE_KEY_PREFIX – If the cache is shared across multiple sites using the same Django installation, set this to the name of the site, or some other string that is unique to this Django instance, to prevent key collisions. Use an empty string if you don't care.

Which mechanism is used to enable caching for an individual view in Django?

Using Memcached One of the most popular and efficient types of cache supported natively by Django is MEMCACHED .

How does Django implement caching?

To use cache in Django, first thing to do is to set up where the cache will stay. The cache framework offers different possibilities - cache can be saved in database, on file system or directly in memory. Setting is done in the settings.py file of your project.

How do you use memcached in Django?

If the developer chooses to use caching and does not specify the CACHE_BACKEND, by default Django will use the :/// symbol. Memcached can be used with Django by setting CACHE_BACKEND to memcached://ip:port/. Here ip is the IP address of the Memcached daemon and port is the port on which the Memcached is running.


1 Answers

As mentioned in the comments, it sounds like you're going to need to handle this with an asynchronous background task, saving the result in the Django low level cache. I would personally use celery for the task queue.

Basically, after page one is requested, you would add an asynchronous task to start the page 2 calculations, storing the result in the cache. So, when page 2 is requested, you check for the pre-rendered response in the cache, and if it doesn't exist, you could calculate the value synchronously.

So, your code would look something like this (the task would be in a task.py file in your app, but this should give you a general idea):

from celery import task
from django.core.cache import cache

def page_two_calculation(arg1, arg2):
    return arg1 + arg2

@task
def page_two_task(arg1, arg2):
    result = page_two_calculation(arg1, arg2)
    cache_key = "page-two-%s-%s" (arg1, arg2)
    cache.set(cache_key, result)

def page_one(request, arg1, arg2):

    # Start the page two task
    page_two_task.delay(arg1, arg2)

    # Return the page one response
    return HttpResponse('page one')

def page_two(request, arg1, arg2)
    cache_key = "page-two-%s-%s" (arg1, arg2)
    result = cache.get(cache_key)
    if result is None:
         # the result will only be None if the page 2 calculation
         # doesn't exist in the cache, in which case we'll have to
         # return the value synchronously.
         result = page_two_calculation(arg1, arg2)
    return result
like image 169
csinchok Avatar answered Sep 27 '22 16:09

csinchok