【问题标题】:A thread-safe template context processor in Django?Django 中的线程安全模板上下文处理器?
【发布时间】:2012-04-06 09:27:20
【问题描述】:

在 Django 中编写线程安全上下文处理器的最佳实践是什么?

说,我想将一些变量传递给模板,这 在相应的视图中设置,并且对于 不同的视图-模板对。

一种解决方案是手动传递上下文中的每个变量:

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

但是,为了保持 DRY,我宁愿使用上下文处理器。但是我 担心线程安全,因为它似乎需要全局存储。 这是我使用上下文处理器的解决方案,它将每个 可变的请求。感谢您的 cmets 和建议。

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

【问题讨论】:

    标签: django django-templates thread-safety django-context


    【解决方案1】:

    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 个变量,并且每个模板只需要其中的一些(但它们因模板而异),那么只需让所有模板都可以使用它们。只要一代不昂贵,这很好用,并记住查询集是惰性的,所以如果你从不评估它们,它们就永远不会命中数据库

    【讨论】:

    • 由于某种原因,为每个视图添加 contextrender_to_response 让我很恼火。所以我遵循了django.comments.中使用的设计但是你的cmets是有道理的。谢谢。
    • 如果您使用 django 1.3+,请考虑使用 render 而不是 render_to_response。添加context 是微不足道的IMO,但添加context_instance=RequestContext(request) 很烦人。新的render 不需要这样做......或者在它们滚动时使用基于类的视图。
    猜你喜欢
    • 2011-01-15
    • 2015-11-01
    • 2015-11-27
    • 2020-04-12
    • 2013-03-05
    • 1970-01-01
    • 2011-08-31
    • 2018-06-03
    • 1970-01-01
    相关资源
    最近更新 更多