Ver índice de contenidos del libro

13.4. La API de cache de bajo nivel

Algunas veces, colocar en cache una página entera no te hace ganar mucho y es, de hecho, un inconveniente excesivo.

Quizás, por ejemplo, tu sitio incluye una vista cuyos resultados dependen de diversas consultas costosas, lo resultados de las cuales cambian en intervalos diferentes. En este caso, no sería ideal usar la página entera en cache que la cache por sitio o por vista ofrecen, porque no querrás guardar en cache todo el resultado (ya que los resultados cambian frecuentemente), pero querrás guardar en cache los resultados que rara vez cambian.

Para casos como este, Django expone una simple API de cache de bajo nivel, la cual vive en el módulo django.core.cache. Puedes usar la API de cache de bajo nivel para almacenar los objetos en la cache con cualquier nivel de granularidad que te guste. Puedes colocar en la cache cualquier objeto Python que pueda ser serializado de forma segura: strings, diccionarios, listas de objetos del modelo, y demás. (La mayoría de los objetos comunes de Python pueden ser serializados; revisa la documentación de Python para más información acerca de serialización).

Aquí vemos como importar la API:

>>> from django.core.cache import cache

La interfaz básica es set(key, value, timeout_seconds) y get(key):

>>> cache.set('my_key', 'hello, world!', 30)
>>> cache.get('my_key')
'hello, world!'

El argumento timeout_seconds es opcional y obtiene el valor del argumento timeout de CACHE_BACKEND, explicado anteriormente, si no se lo especifica.

Si el objeto no existe en la cache, o el sistema de cache no se puede alcanzar, cache.get() devuelve None:

# Wait 30 seconds for 'my_key' to expire...
 
>>> cache.get('my_key')
None
 
>>> cache.get('some_unset_key')
None

Te recomendamos que no almacenes el valor literal None en la cache, porque no podrás distinguir entre tu valor None almacenado y el valor que devuelve la cache cuando no encuentra un objeto.

cache.get() puede recibir un argumento por omisión. Esto especifica qué valor debe devolver si el objeto no existe en la cache:

>>> cache.get('my_key', 'has expired')
'has expired'

Para obtener múltiples valores de la cache de una sola vez, usa cache.get_many(). Si al sistema de cache le es posible, get_many() tocará la cache sólo una vez, al contrario de tocar la cache por cada valor. get_many() devuelve un diccionario con todas las key que has pedido que existen en la cache y todavía no han expirado:

>>> cache.set('a', 1)
>>> cache.set('b', 2)
>>> cache.set('c', 3)
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}

Si una key no existe o ha expirado, no será incluida en el diccionario. Lo siguiente es una continuación del ejemplo anterior:

>>> cache.get_many(['a', 'b', 'c', 'd'])
{'a': 1, 'b': 2, 'c': 3}

Finalmente, puedes eliminar keys explícitamente con cache.delete(). Esta es una manera fácil de limpiar la cache para un objeto en particular:

>>> cache.delete('a')

cache.delete() no tiene un valor de retorno, y funciona de la misma manera si existe o no un valor en la cache.