2010-09-15 6 views
11

En django, escribí una vista que simplemente devuelve un archivo, y ahora estoy teniendo problemas porque Memcache intenta almacenar esa vista en caché, y en sus palabras, "TypeError: puede" t salmuera de objetos de archivo ".Inhabilitar el almacenamiento en caché de una vista o url en django

Como en realidad necesito devolver archivos con esta vista (esencialmente hice una memoria caché basada en archivos para esta vista), lo que tengo que hacer es hacerlo de alguna manera para que Memcache no pueda o no intente para almacenar en caché la vista.

Me imagino que esto se puede hacer de dos maneras. Primero, evite que la vista se guarde en la memoria caché (un decorador tendría sentido aquí), y segundo, evite que la URL se guarde en la memoria caché.

Ninguno parece ser posible, y nadie más parece haberse encontrado con este problema, al menos no en los interwebs públicos. ¿Ayuda?

Actualización: He intentado el decorador @never_cache, e incluso pensé que estaba trabajando, pero al mismo tiempo que establece las cabeceras de modo otras personas no lo hará cosas caché, mi máquina local sigue haciendo.

Respuesta

6

Al devolver un objeto de archivo real y real desde una vista, parece que algo está mal. Puedo ver devolver el contenido de un archivo, alimentando esos contenidos en un objeto HttpResponse. Si te entiendo correctamente, estás almacenando en caché los resultados de esta vista en un archivo. Algo como esto:

def myview(request): 
    file = open('somefile.txt','r') 
    return file # This isn't gonna work. You need to return an HttpRequest object. 

supongo que si se convirtió el almacenamiento en caché fuera enteramente en settings.py, su "no puede conservar en vinagre un objeto de archivo" se convertiría en un "punto de vista debe devolver un objeto de respuesta HTTP. "

Si estoy en el camino correcto con lo que está pasando, entonces aquí hay un par de ideas.

Mencionaste que estás creando un caché basado en archivos para esta vista. ¿Seguro que quieres hacer eso en lugar de solo usar memcached?

Si realmente quiere un archivo, a continuación, hacer algo como:

def myview(request): 
    file = open('somefile.txt','r') 
    contents = file.read() 
    resp = HttpRespnse() 
    resp.write(contents) 
    file.close() 
    return resp 

que va a resolver su problema "no se puede conservar en vinagre un archivo".

+0

Gracias por los comentarios atentos. Sí, básicamente estoy haciendo lo que estás sugiriendo. Y la razón por la que no estoy usando memcached para esto es porque es para los mapas de sitio en el sitio, que tardan 20 segundos en generar (más o menos) y que llenarían muy rápidamente los memcached (tengo alrededor de 600 sitemaps). Mediante el uso de un caché basado en archivos de fabricación propia, se generan una vez y luego se publican de forma coherente. Si alguna vez cambian (normalmente no lo hacen), simplemente elimino los archivos del disco manualmente, ¡y todo está bien! – mlissner

+0

Sorprendentemente, esta fue en última instancia la respuesta. Pensé que mi memoria caché funcionaba correctamente, pero me perdí un área en la que intentaba simplemente devolver un archivo. ¡Uf! Felicitaciones por la recompensa. – mlissner

16
from django.views.decorators.cache import never_cache 

@never_cache 
def myview(request): 
    # ... 

Documentation es aquí ...

+0

Eso impide que * otras * computadoras almacenen cosas en el caché, pero mi instalación local de memcached aún almacena cosas en la caché ... frustrantemente. – mlissner

+0

Si pregunta por el middleware Django cache estándar, esta respuesta es correcta. El marco de caché de Django está controlado por los encabezados estándar HTTP 'Cache-Control' como los configurados por el decorador' @ never_cache'. – jpwatts

+0

Eso es genial de saber. Realmente estoy teniendo dificultades para saber si algo ha sido guardado en la memoria, aparentemente. – mlissner

1

Probablemente hizo una per site cache, pero lo que quiere hacer ahora es un per view cache. El primero es más fácil de implementar, pero solo está pensado para el caso de 'solo almacenar todo en caché'. Como quiera elegir ahora para cada vista, simplemente cambie al enfoque de grano fino. También es muy fácil de usar, pero recuerda que a veces necesitas crear una segunda vista con los mismos contenidos, si quieres que el resultado a veces se guarde en la memoria caché y a veces no, dependiendo de la url.

Hasta ahora a la respuesta a su pregunta. ¿Pero es esa una respuesta a tu problema? ¿Por qué devuelves archivos en una vista? Normalmente, los archivos estáticos como videos, imágenes, css, juegos flash o lo que sea deben ser manejados por el servidor mismo (o incluso por un servidor diferente). Y supongo que eso es lo que quieres hacer desde esa perspectiva. ¿Es eso correcto? La razón por la que no deja que django haga esto es porque iniciar django y dejar que django haga lo suyo también consume muchas resorciones y tiempo. No lo sientes cuando eres el único usuario en tu entorno de prueba. Pero cuando quieres escalar a miles de usuarios o más, este tipo de cosas se vuelve muy desagradable.También desde un punto de vista lógico no parece inteligente, dejar que un programa maneje archivos sin cambiarlos, cuando el trabajo normal del programa es generar o cambiar HTML de acuerdo con un estado de sus datos y una solicitud de usuario. Es como dejar que tu contador haga el trabajo de programación. Si bien él podría hacerlo, probablemente quieras que alguien más lo haga y dejar que el contador se ocupe de tus libros.

+0

Respuesta muy completa, pero la razón por la que estoy haciendo esto es implementar un caché basado en archivos en los sitemaps para el sitio y un caché de memoria en cualquier otro lugar. ¡De manera molesta, hacerlo yo mismo era la única forma en que podía evitar que mis más de 600 mapas de sitios llenaran el caché sin dejar de tener buenas tasas de respuesta! – mlissner

Cuestiones relacionadas