2012-02-23 22 views
16

Tiện ích bộ nhớ cache có bộ trang trí @cache.memoize để lưu vào bộ nhớ cache bao gồm chế độ xem *args**kwargs. Tuy nhiên, một số chế độ xem của tôi cũng lấy chuỗi truy vấn URL, ví dụ: /foo/image?width=640. Trình trang trí thêm phương thức make_cache_key vào chức năng chế độ xem trang trí có thể được sử dụng để tùy chỉnh khóa bộ nhớ cacheflask-cache ghi nhớ thông số chuỗi truy vấn URL cũng như

Tuy nhiên, tôi không biết cách để có được request.args ngoài ngữ cảnh yêu cầu bình thường.

Bất kỳ ý tưởng nào về cách làm cho @cache.memoize cũng hoạt động với chuỗi truy vấn URL?

+2

Bạn có thể trích xuất chức năng thế hệ hình ảnh từ quan điểm và lưu lại kết quả. – reclosedev

+0

Vâng, điều đó đã xảy ra. – Adrian

+1

Đây là một câu trả lời vô cùng bực bội, vì nó đi lên trong một tìm kiếm cho việc sử dụng flask-cache & làm thế nào để quản lý các tuyến đường với params url, nhưng không cung cấp một câu trả lời thực tế. – blueblank

Trả lời

27

Tôi đã có cùng một vấn đề ngày hôm nay và không tìm thấy bất kỳ ví dụ nào trên internet vì vậy tôi đã chơi một chút.

Đây là make_cache_key tôi:

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') 

Bạn có thể sử dụng request.url thay vì đường dẫn và args băm. Tôi cũng cần thêm ngôn ngữ người dùng vào khóa.

Caching một cái nhìn:

@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 

Nó hoạt động nhưng tôi nghĩ rằng nó là loại cồng kềnh. Nó bật ra, rằng key_prefix có thể là một cuộc gọi mà tạo ra toàn bộ cache_key. Do đó, chúng tôi có thể thực hiện việc này:

@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 

Tôi vừa đưa ra điều này và chưa sử dụng nó trong sản xuất - vì vậy nó có thể không hoạt động trong mọi trường hợp.

+7

Cảm ơn! Điều này làm việc cho tôi: 'def make_cache_key (* args, ** kwargs): return request.url' – reubano

+0

Điều này có thể dẫn đến việc tích tụ dữ liệu trùng lặp trong redis có thể không? Nếu bạn yêu cầu nói, '/ comments? Blah = blah', và'/comments? Foo = foo', cả hai đều mang lại kết quả tương tự bởi vì ví dụ args bị bỏ qua, cả hai đáp ứng sẽ được lưu trữ. – reptilicus

+0

@reptilicus Đây là điểm hợp lệ! Nhưng có thể không trình bày một vấn đề thực tế cho người dùng điển hình (họ không nhất thiết phải mucking với URL). Trong mọi trường hợp, một cách tương tự có thể được thực hiện, với sự nhất quán mạnh hơn: 'def make_cache_key (* args, ** kwargs): return (request.path,) + (arg cho arg trong args) + (mục nhập cho mục nhập trong sắp xếp (kwargs.items())) '(chưa được kiểm tra, chỉ là một điểm khởi đầu) – hangtwenty

4

Kể từ phiên bản 0.3.4, key_prefix có thể là một callable:

mới trong phiên bản 0.3.4: tùy chọn có thể là một callable mà không có đối số nhưng trả về một chuỗi sẽ được sử dụng như là cache_key.

Đây là doc: Flask-Cache

+0

memoize() không chấp nhận tham số key_prefix. –

3

nhờ SmoeAsdine El Hrychy, đây là phiên bản của tôi; nó tạo ra một khóa cho chuỗi truy vấn + URL hiện tại (theo ý kiến ​​của tôi, phải là một nhu cầu chung).

Lưu ý:

  • chuỗi truy vấn được sắp xếp trong một nỗ lực để giữ nguyên nếu bạn yêu cầu ?a=foo&b=bar hoặc ?b=bar&a=foo (ban đầu tôi đã làm (k, v) for k, val in flask.request.args.viewitems() for v in sorted(val) nhưng tôi đã thay đổi để sắp xếp các phím quá)
  • nó hỗ trợ cùng với nhiều lần xuất hiện, ví dụ: ?a=foo&a=bar (và sẽ trả lại cùng một khóa với số ?a=bar&a=foo)
  • đối số key_prefix chỉ dành cho cached và không cho memoize, ít nhất là Flask-Cache 0,13.1, và vì nó có đường dẫn URL, nó phải phù hợp với hầu hết các trường hợp sử dụng memoize

Mã:

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) 
0

vì tôi không muốn anh trai mình để làm công việc giống như quote args , nhưng mã sau đây có thể làm việc và có thể đáp ứng yêu cầu của tôi:

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) 
2

Bạn có thể sử dụng flask-caching:

Tiếp tục của Flask-Cache mở rộng

Với mà bạn có thể làm điều gì đó như thế này:

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

Documents từ source code:

: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. 
+1

Tôi chỉ upvote cả hai bình luận của bạn trong GithHub và câu trả lời này;) –

Các vấn đề liên quan