6

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

何が起こるかというとsettings.CACHE_MIDDLEWARE_KEY_PREFIX、起動時に一度設定され、現在のサイトが何であるかに応じて先に進んで変更することはできません. その結果、 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 アプリケーションのキャッシング (低レベルのキャッシングではない) を処理する方法については実際には言及されていません。

4

3 に答える 3

2

(免責事項:以下は純粋に憶測であり、テストされていません。塩のピンチで消費してください。)

'Host'ヘッダーをキャッシュ キーに含めるために、 vary_on_headersビュー デコレータを使用できる場合があります。これにより、HTTP Host ヘッダーを含むキャッシュ キーが生成され、サイトのキャッシュが効果的に分離されます。

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

もちろん、これはビュー単位でしか機能せず、すべてのビューにデコレータを追加する必要があるのは非常に面倒です。

@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
于 2011-02-01T10:38:46.470 に答える
1

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

settings.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])
于 2014-02-13T10:10:39.297 に答える
0

django.util.cache で get_full_path を build_absolute_uri に変更する必要があります

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)

または、マルチサイト用にわずかに変更された独自のキャッシュ ミドルウェアを作成します。 http://macrotoma.blogspot.com/2012/06/custom-multisite-caching-on-django.html

于 2012-06-26T13:08:03.183 に答える