2011-02-01 14 views
6

Tengo una cantidad de sitios en una aplicación de Django en los que me gustaría implementar el almacenamiento en caché de todo el sitio. Sin embargo, está demostrando ser una verdadera molestia.Django - Caché de sitio de múltiples sitios

lo que sucede es que settings.CACHE_MIDDLEWARE_KEY_PREFIX se establece una vez en el inicio, y no puedo continuar y cambiarlo según el sitio actual. Como resultado, si una página de url http://website1.com/abc/ se almacena en caché, entonces http://website2.com/abc/ representa la versión en caché de http://website1.com/abc/. Ambos sitios web se ejecutan en la misma instancia de Django, ya que esto es lo que parece que Django Sites nos permite.

¿Es este un enfoque incorrecto? Como no puedo establecer dinámicamente CACHE_MIDDLEWARE_KEY_PREFIX durante el tiempo de ejecución, no puedo almacenar en caché varios sitios usando el almacenamiento en caché de Django en todo el sitio. Tampoco puedo hacer esto para la plantilla y ver el almacenamiento en caché.

Tengo la impresión de que la forma en que esto realmente necesita configuración es que cada sitio necesita su propia instancia de Django que es prácticamente idéntica excepto por el archivo de configuración, que en mi caso diferirá solo por el valor de CACHE_MIDDLEWARE_KEY_PREFIX. Estas instancias de Django todas leen y escriben en la misma base de datos. Esto me preocupa ya que podría crear una serie de problemas nuevos.

¿Estoy yendo por el camino correcto o me equivoco acerca de cómo la arquitectura multi sitio necesita funcionar? He revisado los documentos de Django y no hay una mención real de cómo manejar el almacenamiento en caché (que no es el almacenamiento en caché de bajo nivel) para las aplicaciones de Django que sirven a varios sitios.

+0

¿Ha encontrado una solución a eso? –

Respuesta

1

(Aviso: La siguiente es puramente especulación y no se ha probado Consumir con una pizca de sal..)

Podría ser posible utilizar el vary_on_headers vista decorador para incluir el 'Host' encabezado en la clave de caché. Esto debería dar como resultado claves de caché que incluyen el encabezado del host HTTP, aislando efectivamente las cachés de sus sitios.

@vary_on_headers('Host') 
def my_view(request): 
    # .... 

Por supuesto, esto sólo funciona sobre una base per-view, y tener que añadir un decorador a todos los puntos de vista puede ser un gran problema.

Al acceder al source of @vary_on_headers, se revela el uso de patch_vary_headers() que uno podría usar en un middleware para aplicar el mismo comportamiento en un nivel de sitio. Algo a lo largo de las líneas de:

from django.utils.cache import patch_vary_headers 

class VaryByHostMiddleware(object): 
    def process_response(self, request, response): 
     patch_vary_headers(response, ('Host',)) 
     return response 
0

Tiene que cambiar get_full_path a build_absolute_uri en django.util.cache

def _generate_cache_header_key(key_prefix, request): 
"""Returns a cache key for the header cache.""" 
#path = md5_constructor(iri_to_uri(request.get_full_path())) 
path = md5_constructor(iri_to_uri(request.build_absolute_uri())) # patch using full path 
cache_key = 'views.decorators.cache.cache_header.%s.%s' % (
    key_prefix, path.hexdigest()) 
return _i18n_cache_key_suffix(request, cache_key) 


def _generate_cache_key(request, method, headerlist, key_prefix): 
"""Returns a cache key from the headers given in the header list.""" 
ctx = md5_constructor() 
for header in headerlist: 
    value = request.META.get(header, None) 
    if value is not None: 
     ctx.update(value) 
#path = md5_constructor(iri_to_uri(request.get_full_path())) 
path = md5_constructor(iri_to_uri(request.build_absolute_uri())) 
cache_key = 'views.decorators.cache.cache_page.%s.%s.%s.%s' % (
    key_prefix, request.method, path.hexdigest(), ctx.hexdigest()) 
return _i18n_cache_key_suffix(request, cache_key) 

O crear su propio middleware de caché ligeramente cambiada para múltiples sitios. http://macrotoma.blogspot.com/2012/06/custom-multisite-caching-on-django.html

1

He enfrentado este problema recientemente. Lo que hice basado en el documentation fue crear un método personalizado para agregar el ID del sitio a la clave utilizada para almacenar en caché la vista.

En configuraciones.py añadir el argumento KEY_FUNCTION:

CACHES = { 
    'default': { 
     'BACKEND': 'path.to.backend', 
     'LOCATION': 'path.to.location', 
     'TIMEOUT': 60, 
     'KEY_FUNCTION': 'path.to.custom.make_key_per_site', 
     'OPTIONS': { 
      'MAX_ENTRIES': 1000 
     } 
    } 
} 

Y mi método make_key personalizado:

def make_key_per_site(key, key_prefix, version): 
    site_id = '' 
    try: 
     site = get_current_site() # Whatever you use to get your site's data 
     site_id = site['id'] 
    except: 
     pass 
    return ':'.join([key_prefix, site_id, str(version), key]) 
+0

get_current_site() requirió un argumento de 'solicitud'. es una buena idea, pero al final no funciona. – Florian

Cuestiones relacionadas