python - route - flask vs django
flask-cache también memoriza los parámetros de la cadena de consulta de URL (5)
La extensión flask-cache tiene un decorador @cache.memoize
para almacenar en caché una vista que incluye los **kwargs
*args
y **kwargs
. Sin embargo, algunas de mis vistas también toman una cadena de consulta de URL, por ejemplo /foo/image?width=640
. El decorador agrega un método make_cache_key
a la función de vista decorada que se puede usar para personalizar la clave de caché
Sin embargo, no sé cómo obtener el request.args
fuera del contexto de solicitud normal.
¿Alguna idea de cómo hacer que @cache.memoize
funcione también con cadenas de consulta de URL?
Desde la versión 0.3.4, key_prefix puede ser invocable:
Nuevo en la versión 0.3.4: Opcionalmente, puede ser un llamable que no toma argumentos pero devuelve una cadena que se utilizará como la clave de caché
Aquí está el doc: Flask-Cache
Gracias a Smoe y Asdine El Hrychy , aquí está mi versión; genera una clave para la URL actual + cadena de consulta (que, en mi opinión, debe ser una necesidad común).
Nota:
- la cadena de consulta se ordena en un intento de permanecer igual si solicita
?a=foo&b=bar
o?b=bar&a=foo
(inicialmente hice(k, v) for k, val in flask.request.args.viewitems() for v in sorted(val)
pero cambié para ordenar las claves también) - admite la misma clave con varias apariciones, es decir
?a=foo&a=bar
(y devolverá la misma clave que?a=bar&a=foo
) -
key_prefix
argumentokey_prefix
es solo paracached
y no paramemoize
, al menos a partir de Flask-Cache 0.13.1, y como toma la ruta de la URL, debe encajar en la mayoría de losmemoize
uso dememoize
El código:
import flask
import urllib
def cache_key():
args = flask.request.args
key = flask.request.path + ''?'' + urllib.urlencode([
(k, v) for k in sorted(args) for v in sorted(args.getlist(k))
])
return key
# ...
import time
@app.route(''/test'')
@cache.cached(timeout=600, key_prefix=cache_key)
def test():
return time.time()
@app.route(''/<value>/test'')
@cache.cached(timeout=3600, key_prefix=cache_key)
def value_test(value):
return flask.jsonify(time=time.time(), value=value)
Hoy tuve el mismo problema y no encontré ningún ejemplo en Internet, así que jugué un poco.
Este es mi make_cache_key:
def make_cache_key(*args, **kwargs):
path = request.path
args = str(hash(frozenset(request.args.items())))
lang = get_locale()
return (path + args + lang).encode(''utf-8'')
Podría usar request.url en lugar de path y el argumento hash. Necesitaba agregar el idioma de los usuarios a la clave también.
Cachear una vista:
@app.route("/test")
@cache.cached(timeout=50)
def test():
a = request.args.get(''a'')
b = request.args.get(''b'')
return a + b
test.make_cache_key = make_cache_key
Funciona pero creo que es algo engorroso. Resultó que el prefijo clave puede ser invocable, lo que genera la clave de caché completa. Por lo tanto podemos hacer esto:
@app.route("/test2")
@cache.cached(timeout=50, key_prefix=make_cache_key)
def test2():
a = request.args.get(''a'')
b = request.args.get(''b'')
return a + b
Se me ocurrió esto y aún no lo he usado en producción, por lo que puede que no funcione en todos los casos.
Puede utilizar flask-caching
:
Continuación de la extensión Flask-Cache
Con lo que puedes hacer algo como esto:
@app.route("/")
@cache.cached(timeout=10, query_string=True)
def index():
return render_template(''index.html'')
Documentos del código fuente :
:param query_string: Default False. When True, the cache key
used will be the result of hashing the
ordered query string parameters. This
avoids creating different caches for
the same query just because the parameters
were passed in a different order. See
_make_cache_key_query_string() for more
details.
ya que no quiero que el propio hermano haga más trabajo como citar los argumentos, pero el siguiente código puede funcionar y puede satisfacer mi requisito:
from flask import request
def cache_key():
return request.url
@main.route("/test/", methods=[''GET''])
@cache.cached(timeout=10, key_prefix=cache_key)
def do_somthing():
return "hello %s" % str(request.args)