4

Django プロファイル オブジェクトへのアクセスをキャッシュしようとしています。このプロジェクトでデータをキャッシュするために django-redis-cache を使用しています。プロファイルが存在しない場合に自動的にプロファイルを作成するためのスニペットを使用しています。これが私がやっていることの簡略化されたバージョンです(キャッシュなし):

User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])

プロファイル情報が必要なときはいつでも、user.profile プロパティにアクセスします。これは期待どおりに機能しますが、Exhibit 1 のようにプロファイル プロパティをキャッシュしようとすると、プロファイルを選択していてキャッシュを利用していない SQL クエリが (django-debug-toolbar に) 表示されます。

具体的には、資料 2 の cache_object_list() 関数は、キャッシュされた値が使用可能かどうかを確認するコードです。存在する場合は、キャッシュ キーを呼び出します。そうでない場合は、("query" 引数を介して) 渡されたクエリを実行し、結果をキャッシュします。

cache_object_list() は、キャッシュのヒットまたはミスを示す "Hit" または "Miss" を出力します。2 回更新した後、すべてがヒットとして報告されます (予想どおり)。ただし、django-debug-toolbar ではクエリ数が減少せず、プロファイルを選択するクエリが表示されます。

user.profile がキャッシュされたバージョンのプロファイルを利用可能になったときに確実にプルする方法について、誰かアドバイスはありますか? 読んでくれてありがとう。

資料 1: myproject/myapp/models.py

def get_or_create_profile(u):
    return cache_utils.cache_single_object(
        "user_get_or_create_profile",
        u.id, UserProfile.objects.get_or_create(user=u)[0]) 

User.profile = property(lambda u: cache_utils.cache_single_object(
                    "user_get_or_create_profile", u.id,  
                     get_or_create_profile(u)))

資料 2: myproject/cache_utils.py

def cache_single_object(key_prefix, id, query, timeout=500):
    key = '%s_%s' % (key_prefix, id)
    object_list = cache.get(key, None)
    if object_list is None:
        print "Miss %s" % (key)
        object_list = query
        cache.set(key, object_list, timeout)
    else:
        print "Hit  %s" % (key)
    return object_list

図表 3: myproject/templates/mytemplate.py

<div>Example of what's in the template </div>
{{ myobject.owner.profile.bio }} 
4

1 に答える 1

2

問題は、メソッドの定義方法に関連していると思います....

User.profile = property(lambda u: cache_utils.cache_single_object(
                "user_get_or_create_profile", u.id,  
                 get_or_create_profile(u)))

プロファイル プロパティにアクセスするときは、常に以下を呼び出すメソッド get_or_create_profile(u) を呼び出します。

return cache_utils.cache_single_object(
    "user_get_or_create_profile",
    u.id, UserProfile.objects.get_or_create(user=u)[0]) 

UserProfile.objects.get_or_create(user=u) を使用すると、キャッシュにデータが既にある場合でも、毎回クエリを作成しているものがあります。呼び出すたびにクエリを評価しない util メソッドを使用してみてください。多分このようなもの: https://stackoverflow.com/a/2216326/234304

于 2012-09-26T03:03:16.760 に答える