0

次のように、メモ化された Django モデルマネージャーメソッドがあります。

class GroupManager(models.Manager):
    def get_for_user(self, user):
        cache_key = 'groups_%s' % (user.id)
        if not hasattr(self, key):
            groups = get_groups_somehow()
            setattr(self, cache_key, groups)
        return getattr(self, cache_key)

ただし、メモ化された値は、要求/応答サイクルを超えて持続します。つまり、サーバーが再起動されるまで、後続のリクエストで値が再計算されることはありません。これは、マネージャー インスタンスが破棄されていないためです。

では、モデル マネージャーのメソッドを適切にメモ化するにはどうすればよいでしょうか。

4

2 に答える 2

0

キーが存在すると再計算されないように指示したため、キー値は再計算されません。後続の呼び出しで再計算する場合は、コードを並べ替えます

class GroupManager(models.Manager):
    def get_for_user(self, user):
        cache_key = 'groups_%s' % (user.id)
        groups = get_groups_somehow()
        setattr(self, cache_key, groups)
        return getattr(self, cache_key)

また、再計算せずにキャッシュされた値を取得したい場合はgetattr、マネージャーで正しいキーを使用してください。

于 2012-05-18T00:25:49.190 に答える
0

https://stackoverflow.com/a/1526245/287923からインスピレーションを得て、単純化して、次のようにリクエスト キャッシュを実装しました。

from threading import currentThread

caches = {}

class RequestCache(object):
    def set(self, key, value):
        cache_id = hash(currentThread())
        if caches.get(cache_id):
            caches[cache_id][key] = value
        else:
            caches[cache_id] = {key: value}

    def get(self, key):
        cache_id = hash(currentThread())
        cache = caches.get(cache_id)
        if cache:
            return cache.get(key)
        return None

class RequestCacheMiddleware(object):
    def process_response(self, request, response):
        cache_id = hash(currentThread())
        if caches.get(cache_id):
            del(caches[cache_id])
        return response

cachesget&setメソッドを介してアクセスされるキャッシュ ディクショナリのディクショナリです。process_responseミドルウェアは、応答がレンダリングされた後、メソッド内の現在のスレッドのキャッシュをクリアします。

次のように使用されます。

from request_cache import RequestCache
cache = RequestCache()
cache.get(key)
cache.set(key, value)
于 2012-05-20T19:29:51.060 に答える