Globedia.com

×

Error de autenticación

Ha habido un problema a la hora de conectarse a la red social. Por favor intentalo de nuevo

Si el problema persiste, nos lo puedes decir AQUÍ

×
×
Recibir alertas

¿Quieres recibir una notificación por email cada vez que Sal Aguilar escriba una noticia?

Django Suite IV: Hablemos un poco de caché.

18/01/2013 15:40 0 Comentarios Lectura: ( palabras)

Decía Phil Karlton "Solo hay dos cosas dificiles en las ciencias de la computación: invalidación de caché y nombrar cosas."

En esta entrega de la serie Django Suite - después de mas de un año de ausencia - hablaré sobre el framework de caché de Django.

Principios de caché

Cuando hacemos un sitio, especialmente si estamos comenzando no tomamos en cuenta el desempeño del sitio y la cantidad de tiempo de procesamiento por cada petición. El tiempo de procesamiento de un sitio está afectado por varios factores el mas importante la cantidad de consultas que realizamos a la base de dato por cada request, generalmente estas varían según la complejidad de nuestras vistas y el tipo de usuario (anónimo o autenticado) que tengamos en el sitio.

Para mejorar el desempeño del sitio se usa el caché que no es mas que un almacenamiento rápido, generalmente en RAM, que nos evita recaer en operaciones de cálculo pesadas como lo son hacer muchas consultas de base de datos la lógica de las vistas y el renderizado de las mismas en la plantilla que normalmente son realizadas haciendo lectura/escritura de disco duro que agrega mas tiempo a la receta.

Hacer caché de datos no es tan dificil, lo dificil es saber cuando los datos cacheados ya no son válidos y debemos de recalcular de nuevo para construir un nuevo caché, de ahí la frase del inicio del post.

Caché framework

Django contiene un framework de caché que abstrae las operaciones básicas, sin que nosotros tengamos que preocuparnos por el motor de caché que usemos, por defecto Django soporta Memcached, caché en base de datos, caché en el sistema de archivos y memoria local, siendo no muy recomendados estos últimos tres.

Pero como todo en Django la comunidad da soporte para otros motores de caché opensource muy buenos ademas de memcached, como por ejemplo:

Caché de vistas

Django nos provee con el decorador cache_page para hacer caché a una vista, el decorador lo que hace es lo siguiente.

Si la vista ha sido cargada por primera vez, hace todas las operaciones y la guarda en caché con tiempo de vencimiento designado en la llamada del decorador, caso contrario carga el resultado de la vista desde caché.

Ejemplo:

 from   django  .  views  .  Decorators  .  cache   import   cache_page 

 @  cache_page  ( 60  *  15 ) 
 def   my_view  (  request  ): 
     .... 

El valor de 60 * 15 representa la duración de la validez del caché en segundos, en este caso 15 minutos, se acostumbra mucho para asignar valores de vencimiento poner multiplicaciones de la cantidad de segundos en un minuto (60) por el número de minutos deseado.

En el caso que la vista tuviera parámetros como un mi_vista(request, post_id) el caché ser haría de manera individual por cada valor de post_id que tengamos presente. Mas detalles de esto en la documentación oficial.

Caché de fragmentos de plantillas

Fragmentos plantillas también pueden ser cacheadas, esto es especialmente útil para fragmentos que repetimos en casi todas las páginas, por ejemplo elementos de menú dinámicos, columnas de 'últimas noticias' o 'últimos post' en caso de ser un blog.

Ejemplo:

 {  % load cache %} 
 {  % cache 500 menu %} 
     ..   mi   super   menu   de   p á gina   .. 
 {  % endcache %} 

Igual acá la template tag de cache acepta como parámetros la duracion en segundos, el nombre del fragmento y el conjunto de variables que deseamos establecer en el cache.

Este conjuto de variables es tremendamente útil para hacer caché en diversas situaciones tales como si el usuario está o no autenticado, el lenguaje del navegador del usuario ( en caso que usemos la opción de internacionalización y localización del sitio ), valor de alguna varible que usemos que puede modificar el resultado de la plantilla entre otros.

Ejemplo en código fuente de la vida real acá.

Generalmente la mejor documentación es el código fuente, y para verdaderamente entender y jugar con esta template tag recomiendo que vean como está hecha en este archivo

Caché manual

Si queremos verdaderamente sacar provecho al framework de caché de django tenemos que tomar ventaja del API de caché manual. Los motores de caché se basan en almacenamiento de llave-valor (hashmap) o en lo que python seríá un equivalente al tipo diccionario.

El api de caché es bastante simple, podemos ver su uso en el siguiente código fuente:

 #importamos el objeto caché 
 from   django  .  core  .  cache   import   cache 

 #guardamos algo en el cache con expiración de 60 segundos 
 cache  .  set  (  'a'  ,   'un valor cacheado'  ,  60 ) 
 #leemos algo desde cache 
 valor   =   cache  .  get  (  'a'  ) 
 #borramos 'a' del cache  
 cache  .  delete  (  'a'  ) 

Básicamente esa es el API de bajo nivel, si nosotros ponemos como valor de tiempo 0 el caché nunca se vencerá y tendremos que eliminarlo manualmente a posteriori.

Trucos con el caché manual.

El caché manual es tremendamente útil usándolo en conjunto con modelos. Un ejemplo sencillo y fácil de implementar es un menú dinámico, recientemente programé uno que se veía algo así:

 #models.py 
 from   django  .  db   import   models 
 from   django  .  core  .  cache   import   cache  
 
 class   Menu  (  models  .  Model  ): 
     titulo   =   models  .  CharField  (  max_length  = 50 ) 
     url   =   models  .  URLField  () 
     peso   =   models  .  PositiveIntegerField  (  default  = 0 , 
             help_text  =  "peso del elemento del menú, entre mayor sea el número mas hacia el fondo estará el elemento"  ) 
 
     def   save  (  self  ,   *  args  ,   **  kwargs  ): 
         #primero guardamos 
         return_value   =   super  (  ElementoNavegacion  ,   self  ).  save  (  *  args  ,   **  kwargs  ) 
         #invalidamos el cache antiguo de menu 
         cache  .  delete  (  'menu'  ) 
         #creamos el nuevo cache refrescado 
         cache  .  set  (  'menu'  ,   Menu  .  objects  .  all  (),  0 ) 
         return   return_value 
 
     def   __unicode__  (  self  ): 
         return   "%s (%s)"   % (self.titulo, self.url) 

Se creó un context manager para tener la lista del menú en todas las plantillas.

    #context manager para el menú. 
    from   django  .  core  .  cache   import   cache  
    
    from   models   import   Menu 
    
    def   menu_context_manager  (  request  ): 
        #probamos si esta el elemento en caché 
        valor   =   cache  .  get  (  'menu'  ) 
        #si no está leemos de la base de datos 
        if   not   valor  : 
            valor   =   Menu  .  objects  .  all  () 
            #lo cacheamos 
            cache  .  set  (  'menu'  ,   valor  ,  0 ) 

        return   {  'menu'  :   valor  } 

Haciendo esto se ahorran un par de consultas a la base de datos y por ende la velocidad de carga del sitio aumenta.

Despedida

En resumen hemos visto una introducción al cache framework de Django, espero que les haya servido y tendré que hacer un post de continuación para exponer otros casos de uso del caché manual y trucos con el API, además del caché al lado del servidor de archivos estáticos y del lado del navegador.


Sobre esta noticia

Autor:
Sal Aguilar (221 noticias)
Fuente:
tecnologico.com.ni
Visitas:
238
Tipo:
Reportaje
Licencia:
Creative Commons License
¿Problemas con esta noticia?
×
Denunciar esta noticia por

Denunciar

Etiquetas

Comentarios

Aún no hay comentarios en esta noticia.