0

Django でスレッドセーフなコンテキスト プロセッサを作成するためのベスト プラクティスは何ですか?

たとえば、いくつかの変数をテンプレートに渡したいとします。これらの変数は、対応するビューに設定されており、ビューとテンプレートのペアごとに異なる可能性があります。

1 つの解決策は、コンテキスト内の各変数を手動で渡すことです。

return render_to_response('template.html', {'var1':var1,... 'var10':var10},
                           context_instance=RequestContext(request))

ただし、それを DRY に保つには、むしろコンテキスト プロセッサを使用します。しかし、グローバル ストアが必要なように見えるため、スレッド セーフが心配です。これは、各変数をリクエストに結び付けるコンテキスト プロセッサを使用した私のソリューションです。コメントと提案をありがとう。

context_processor.py

store = {}
def add_context(request, key, value):
    if request not in store:
        store[request] = {}
    store[request][key] = value
    return
def misc_context_processor(request):
    return store.pop(request,{})

views.py

import context_processor
def view(request):
    ...
    if x == y:
        context_processor.add_context(request,'var1','value1')
    else:
        context_processor.add_context(request,'var2','value2')
    ...
    return render_to_response('template.html', {},
                              context_instance=RequestContext(request))

settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.request',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    ...,
    'appname.context_processor.misc_context_processor',
)
4

1 に答える 1

0

context_processors は、すべてのテンプレートで使用できるようにすべてのビューで設定するコンテキスト変数用です。ビュー固有のコンテキストがある場合、それは当然ビューに属します。ビュー固有のコンテキスト ディクショナリの構築を context_processor にプッシュしようとしている場合、他の誰かがコードに触れなければならない場合、不要な頭痛と地雷が実際に作成されます。ツールは、本来の目的のために使用してください。

さらに、書き込みと読み取りがはるかに簡単です。

context = {
    'var1': value1,
    'var2': value2,
}

これが何をしているのかを理解しようとするよりも:

context_processor.add_context(request, 'var1', value1)
context_processor.add_context(request, 'var2', value2)

または、あなたが望むのは次のようなものかもしれません:

def view(request):
    context = {}
    ...
    if x == y:
        context['var1'] = value1
    else:
        context['var2'] = value2
    ...
    return render_to_response('template.html', context,
            context_instance=RequestContext(request))

または多分使用するcontext.update({ 'var1': value1 })

2番目の方がDRYである方法がわかりません。とにかくそれらの変数を必要とするすべてのビューでそれをしなければならないことを考えると...

反復可能なコンテキスト生成がある場合は、クラスベースのビューを使用して、それを合理的な方法で抽象化します。本当に 10 個の変数しかなく、各テンプレートがそれらの一部のみを必要とする場合 (ただし、変数はテンプレートごとに異なります)、単純にすべての変数をすべてのテンプレートで使用できるようにします。世代が高価でない限り、これはうまく機能します。クエリセットは遅延しているため、評価しないとデータベースにヒットしないことに注意してください

于 2012-03-21T20:45:51.020 に答える