флеш-кеш также запоминает параметры строки запроса URL - PullRequest
19 голосов
/ 23 февраля 2012

Расширение фляги-кэша имеет декоратор @cache.memoize для кэширования представления, включая *args и **kwargs представления.Однако некоторые из моих представлений также принимают строку запроса URL, например /foo/image?width=640.Декоратор добавляет метод make_cache_key к функции оформленного представления, который можно использовать для настройки ключа кэша

Однако я не знаю, как получить request.args вне обычного контекста запроса.

Есть идеи, как заставить @cache.memoize работать и со строками URL-запросов?

Ответы [ 5 ]

28 голосов
/ 10 января 2013

У меня была такая же проблема сегодня, и я не нашел ни одного примера в интернете, поэтому немного поиграл.

Это мой 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')

Вы можете использовать request.url вместо path и хэшированных аргументов. Мне также нужно было добавить язык пользователя к ключу.

Кэширование представления:

@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

Это работает, но я думаю, что это довольно громоздко. Оказалось, что key_prefix может быть вызываемым, который генерирует весь cache_key. Поэтому мы можем сделать это:

@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

Я только что придумал это и еще не использовал его в производстве - так что он может работать не во всех случаях.

13 голосов
/ 08 ноября 2017

Вы можете использовать flask-caching:

Продолжение расширения Flask-Cache

С помощью которого вы можете сделать что-то вроде этого:

@app.route("/")
@cache.cached(timeout=10, query_string=True)
def index():
    return render_template('index.html')

Документы от исходный код :

: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.
4 голосов
/ 26 августа 2013

Начиная с версии 0.3.4, key_prefix может вызываться:

Новое в версии 0.3.4: при желании может быть вызываемым, которое не принимает аргументов, но возвращает строку, которая будет использоваться в качестве ключа cache_ *. 1004 *

Вот документация: Кеша-колба

3 голосов
/ 22 июля 2015

благодаря Smoe и Asdine El Hrychy , вот моя версия;он генерирует ключ для текущего URL + строка запроса (что, на мой взгляд, должно быть обычной потребностью).

Примечание:

  • строка запроса сортируется при попыткеостаться прежним, если вы запрашиваете ?a=foo&b=bar или ?b=bar&a=foo (изначально я сделал (k, v) for k, val in flask.request.args.viewitems() for v in sorted(val), но я также изменил сортировку ключей)
  • он поддерживает один и тот же ключ с несколькими вхождениями, то есть: ?a=foo&a=bar (и вернет тот же ключ, что и ?a=bar&a=foo)
  • key_prefix аргумент только для cached, а не для memoize, по крайней мере, наFlask-Cache 0.13.1, и, поскольку он принимает путь URL, он должен соответствовать большинству memoize вариантов использования

Код:

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)
1 голос
/ 18 ноября 2016

, поскольку я не хочу, чтобы сам брат выполнял больше работы, например, цитировал аргументы, но следующий код может работать и может удовлетворить мое требование:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...