2011-02-01 7 views
6

1つのDjangoアプリケーションの下にサイトワイドキャッシングを実装したいサイトがいくつかあります。しかし、それは本当の面倒であることが証明されています。Django - 複数のサイトのサイトキャッシング

起動時にsettings.CACHE_MIDDLEWARE_KEY_PREFIXが1回設定され、現在のサイトの内容に応じて変更することはできません。その結果、URL http://website1.com/abc/のページがキャッシュされた場合、http://website2.com/abc/はキャッシュされたバージョンhttp://website1.com/abc/をレンダリングします。これらのWebサイトは、同じDjangoインスタンス上で実行されていますが、これはDjangoサイトが私たちにできるように見えるものです。

これは不正な方法ですか?実行時に動的にCACHE_MIDDLEWARE_KEY_PREFIXを設定することはできないため、Djangoのサイト全体のキャッシュを使用して複数のサイトをキャッシュすることはできません。私はテンプレートとビューキャッシングのためにこれを行うこともできません。

実際にセットアップする必要があるという印象を受けるのは、それぞれのサイトが設定ファイルを除いてほとんど同一のDjangoインスタンスを必要とするということです。私の場合はCACHE_MIDDLEWARE_KEY_PREFIXという値だけが異なります。これらのDjangoインスタンスはすべて同じデータベースを読み書きします。これは数多くの新しい問題を生み出す可能性があるため、私には心配です。

私は正しい道を歩いているのですか、あるいは私はマルチサイトアーキテクチャがどのように動作する必要があるのか​​間違っていますか?私はDjangoのドキュメントをチェックしましたが、複数のサイトに対応するDjangoアプリケーションのキャッシング(低レベルのキャッシングではない)をどのように処理するのかについては言及していません。

+0

あなたはその解決策を見つけましたか? –

答えて

1

(免責事項:以下は、純粋に憶測され、テストされていませんひとつまみの塩で消費。。)

「ホスト」が含まれるようにvary_on_headersビューデコレータを使用することが可能であるかもしれませんヘッダーをキャッシュキーに追加します。これにより、HTTPホストヘッダーを含むキャッシュキーが生成され、サイトのキャッシュが効果的に分離されます。もちろん

@vary_on_headers('Host') 
def my_view(request): 
    # .... 

、それが唯一のビュー単位で動作しますし、すべてのビューにデコレータを追加したことは、大きな手間ことができます。

source of @vary_on_headersを参照すると、ミドルウェアでサイトレベルで同じ動作を適用するために使用できるpatch_vary_headers()の使用が明らかになります。線に沿って何か:

from django.utils.cache import patch_vary_headers 

class VaryByHostMiddleware(object): 
    def process_response(self, request, response): 
     patch_vary_headers(response, ('Host',)) 
     return response 
0

あなたがdjango.util.cache

def _generate_cache_header_key(key_prefix, request): 
"""Returns a cache key for the header cache.""" 
#path = md5_constructor(iri_to_uri(request.get_full_path())) 
path = md5_constructor(iri_to_uri(request.build_absolute_uri())) # patch using full path 
cache_key = 'views.decorators.cache.cache_header.%s.%s' % (
    key_prefix, path.hexdigest()) 
return _i18n_cache_key_suffix(request, cache_key) 


def _generate_cache_key(request, method, headerlist, key_prefix): 
"""Returns a cache key from the headers given in the header list.""" 
ctx = md5_constructor() 
for header in headerlist: 
    value = request.META.get(header, None) 
    if value is not None: 
     ctx.update(value) 
#path = md5_constructor(iri_to_uri(request.get_full_path())) 
path = md5_constructor(iri_to_uri(request.build_absolute_uri())) 
cache_key = 'views.decorators.cache.cache_page.%s.%s.%s.%s' % (
    key_prefix, request.method, path.hexdigest(), ctx.hexdigest()) 
return _i18n_cache_key_suffix(request, cache_key) 

にbuild_absolute_uriそれともマルチサイトのために少し変更されたキャッシュミドルウェアを所有して作成するget_full_pathを変更する必要があります。 http://macrotoma.blogspot.com/2012/06/custom-multisite-caching-on-django.html

1

最近この問題に直面しました。私がdocumentationに基づいて行ったことは、ビューをキャッシュするために使用されたキーにサイトIDを追加するためのカスタムメソッドを作成することでした。

設定されています。PY KEY_FUNCTION引数を追加します。

CACHES = { 
    'default': { 
     'BACKEND': 'path.to.backend', 
     'LOCATION': 'path.to.location', 
     'TIMEOUT': 60, 
     'KEY_FUNCTION': 'path.to.custom.make_key_per_site', 
     'OPTIONS': { 
      'MAX_ENTRIES': 1000 
     } 
    } 
} 

そして、私のカスタムmake_key方法:

def make_key_per_site(key, key_prefix, version): 
    site_id = '' 
    try: 
     site = get_current_site() # Whatever you use to get your site's data 
     site_id = site['id'] 
    except: 
     pass 
    return ':'.join([key_prefix, site_id, str(version), key]) 
+0

get_current_site()には 'request'引数が必要です。いいアイデアですが、最終的には機能しません。 – Florian

関連する問題