web-dev-qa-db-ja.com

クエリ結果のキャッシュdjango

頻繁に変化しないクエリの結果をキャッシュする方法を見つけようとしています。たとえば、eコマースの製品のカテゴリ(携帯電話、テレビなど)。テンプレートフラグメントキャッシングの使用を考えていますが、このフラグメントでは、これらのカテゴリのリストを反復処理します。このリストはサイトのどの部分でも利用できるので、私のbase.htmlファイル。テンプレートをレンダリングするときに、常にカテゴリのリストを送信する必要がありますか?または、テンプレートで常にリストを使用可能にする、これを行うためのより動的な方法がありますか?

42
Marcio Cruz

キャッシュされたクエリを Djangoのキャッシュ にポップします:

from Django.core.cache import cache

cache.set('key', queryset)

次に、コンテキストプロセッサを作成して、キャッシュの値をすべてのテンプレートに追加します。

# myproject/myapp/context_processors.py

from Django.core.cache import cache

def cached_queries():
    return {'cache', cache.get('key')}

次に、コンテキストプロセッサを Django設定ファイル に追加します。

TEMPLATE_CONTEXT_PROCESSORS += (
    'myproject.myapp.context_processors.cached_queries'
)

これで、すべての汎用テンプレートおよびリクエストコンテキストを持つすべてのテンプレートのcache変数にアクセスできるようになります。これは、ビューでこれを行うとテンプレートが与えられます。

return render_to_response('my_template.html',
                          my_data_dictionary,
                          context_instance=RequestContext(request))

キャッシュを設定するタイミング

キャッシュに含まれるものに依存します。しかし、よくある問題は、Djangoが実際にページリクエストが送信されるたびにPythonを実行するだけであり、この種の作業を行う場所ではないことです。

別の方法は、特定のアプリに対して カスタム管理コマンド を作成することです。その後、必要に応じてこれを手動で実行するか、より一般的には cron job として実行するように設定します。

管理コマンドを作成するには、アプリ内にあるmanagement/commandsディレクトリ内のCommandから派生したクラスを作成する必要があります。

# myproject/myapp/management/commands/update_cache.py

from Django.core.management.base import NoArgsCommand
from Django.core.cache import cache

class Command(NoArgsCommand):
    help = 'Refreshes my cache'

    def handle_noargs(self, **options):
        cache.set('key', queryset)

これはコマンドの名前になるため、このファイルの名前は重要です。この場合、コマンドラインでこれを呼び出すことができます:

python manage.py update_cache
70
Marcus Whybrow

johnny-cache を使用して、クエリセットの自動キャッシングを行うこともできます。 (デフォルトで)すべてのクエリセットをキャッシュしますが、一部をキャッシュしないように強制できます。

13