Потоково-безопасный шаблонный контекстный процессор в Django? - PullRequest
0 голосов
/ 21 марта 2012

Какова лучшая практика для написания поточно-ориентированного контекстного процессора в Django?

Скажем, я хочу передать некоторые переменные шаблонам, которые установлены в соответствующих представлениях и могут отличаться для разныхпары шаблон-вид.

Одним из решений было бы вручную передать каждую переменную в контексте:

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

Однако, чтобы она оставалась СУХОЙ, я бы предпочел использовать процессор контекста.Но я беспокоюсь о безопасности потоков, так как для этого требуется глобальное хранилище.Вот мое решение с использованием контекстного процессора, который связывает каждую переменную с запросом.Спасибо за ваши комментарии и предложения.

В 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',
)

1 Ответ

0 голосов
/ 22 марта 2012

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 })

Я скучаю, как второйболее сухой.Учитывая, что вам придется делать это в каждом представлении, которому все равно нужны эти переменные ...

Если у вас есть повторяемая генерация контекста, используйте представления на основе классов, чтобы разумным образом это абстрагировать.Если у вас действительно есть 10 переменных, и каждому шаблону нужны только некоторые из них (но они варьируются от шаблона к шаблону), то просто сделайте их все доступными для всех шаблонов.Пока поколение не дорого, это прекрасно работает, и имейте в виду, что наборы запросов ленивы, поэтому, если вы никогда не оцените их, они никогда не достигнут db

...