我有一个带菜单的网站。要生成菜单,我需要在数据库中进行一些查询。所以我创建了一个上下文处理器来在我的所有视图中完成它。
我的一些观点实际上是形式。当我的用户点击某些按钮时,我使用ajax并使用jquery ui对话框显示它们。
我无法删除那些非常复杂的表单的所有上下文处理器,特别需要auth,static和il8n上下文处理器。 但我不想在数据库中创建基于菜单的查询来显示这些表单。
有没有办法在视图中排除上下文处理器? 我试图在视图中的“request.session”中放置一个变量,然后删除它并在我的上下文处理器中返回一个空字典。但它非常糟糕,并且可能存在并发问题。 我也可以在我的上下文处理器中解析“请求”中的url并返回一个空字典,但它听起来像是一个黑客。
有任何想法或建议吗? 谢谢,
答案 0 :(得分:3)
这就是Django的懒惰对象。您可以提供具有关联函数的惰性对象,而不是计算上下文处理器中的实际内容;当某些东西实际上试图使用该对象时,例如在模板中,然后它调用该函数。 This answer给出了同一问题的示例。
如果多次使用变量,请注意记忆;一些选项会重新调用该函数,而有些则会保存结果。您可以查看the source以确定。我认为SimpleLazyObject
(如上面的答案中所做的那样)可以做你想要的,但我最近没有用过这个来确定。
(按要求回答......)
答案 1 :(得分:2)
您可以在RequestContext
中继承django.template.context
并重新定义其__init__
方法。然后,您可以在这些特定视图中使用此修改后的RequestContext
。 __init__
的{{1}}目前看起来像这样:
def __init__(self, request, dict=None, processors=None, current_app=None, use_l10n=None): Context.__init__(self, dict, current_app=current_app, use_l10n=use_l10n) if processors is None: processors = () else: processors = tuple(processors) for processor in get_standard_processors() + processors: self.update(processor(request))
在此处,RequestContext
返回您设置中定义的上下文处理器。在调用上下文处理器(上面代码的最后一行)之前,您可以添加一个检查来确定需要使用哪些处理器以及需要跳过哪些处理器。
答案 2 :(得分:2)
重新设计您的应用可能更容易,以便某些观看次数可以进行此查询,而有些则不会。您可以通过编写一个“基于类的视图”来避免这种情况,这种视图会使这个特定的数据库查询并将其添加到上下文中,然后在您希望新视图进行额外查询时继承它。我主张采用这种方法而不是全局上下文处理器。
This example显示了如何向默认模板上下文添加内容。
答案 3 :(得分:1)
使用各种模板引擎很容易实现。
TEMPLATES = [
# The default engine - a heavy one with a lot of context processors
{
'NAME': 'default',
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.template.context_processors.i18n',
'django.template.context_processors.request',
'django.template.context_processors.media',
'django.template.context_processors.static',
'some_app_1.context_processors.very_heavy_cp_1',
'some_app_2.context_processors.very_heavy_cp_2',
'some_app_3.context_processors.very_heavy_cp_3',
],
'debug': True,
},
},
# Light engine - only very necessary things go here
{
'NAME': 'light',
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.template.context_processors.i18n',
'django.template.context_processors.request',
'django.template.context_processors.media',
'django.template.context_processors.static',
],
'debug': True,
},
},
]
some_app_1.views.py
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.generic import View, TemplateView
示例灯光视图:
class TestLightView(View):
"""Test light view."""
template_name = 'some_app_1/test_light_view.html'
def get(self, request):
context = {}
response = render_to_response(
self.template_name,
context,
context_instance=RequestContext(request),
using='light' # Note, that we use `light` engine here
)
return response
正常(重)视图示例:
class TestNormalView(View):
"""Test normal view."""
template_name = 'some_app_1/test_normal_view.html'
def get(self, request):
context = {}
response = render_to_response(
self.template_name,
context,
context_instance=RequestContext(request),
using='default' # Note, that we use `default` engine here
)
return response
如果您使用TemplateView
,请定义template_engine
属性。
示例灯光视图:
class TestTemplateLightView(TemplateView):
"""Test template light view"""
template_engine = 'light' # Note, that we use `light` engine here
# Your code goes here
正常(重)视图示例:
class TestTemplateNormalView(TemplateView):
"""Test template normal view."""
template_engine = 'default' # Note, that we use `default` engine here
# Your code goes here