在django中创建我自己的上下文处理器

时间:2010-05-23 22:19:00

标签: django views django-context

我已经到了需要将某些变量传递给我的所有视图(主要是自定义身份验证类型变量)的地方。

我被告知编写自己的上下文处理器是最好的方法,但我遇到了一些问题。

我的设置文件如下所示

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.contrib.auth.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "django.contrib.messages.context_processors.messages",
    "sandbox.context_processors.say_hello", 
)

正如你所看到的,我有一个名为'context_processors'的模块和一个名为'say_hello'的函数。

看起来像

def say_hello(request):
        return {
            'say_hello':"Hello",
        }

我是否正确地假设我现在可以在我的观点中执行以下操作?

{{ say_hello }}

现在,这在我的模板中没有任何内容。

我的观点看起来像

from django.shortcuts import render_to_response

def test(request):
        return render_to_response("test.html")

5 个答案:

答案 0 :(得分:47)

您编写的上下文处理器应该可以正常工作。问题出在你看来。

您是否肯定使用RequestContext呈现您的观点?

例如:

def test_view(request):
    return render_to_response('template.html')

上面的视图不会使用TEMPLATE_CONTEXT_PROCESSORS中列出的上下文处理器。确保您提供的RequestContext如此:

def test_view(request):
    return render_to_response('template.html', context_instance=RequestContext(request))

答案 1 :(得分:28)

根据django docs,您可以使用render作为快捷方式,而不是使用context_instance参数的render_to_response:

  

或者,使用render()快捷方式,该快捷方式与对render_to_response()的调用相同,并使用强制使用RequestContext的context_instance参数。

答案 2 :(得分:9)

从Django 1.8开始,你就注册了这样的自定义上下文处理器:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            'templates'
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'www.context_processors.instance',
            ],
        },
    },
]

假设您的上下文处理器位于www

中的应用context_processors.py

答案 3 :(得分:2)

如果您使用Django的render_to_response()快捷方式使用字典的内容填充模板,则默认情况下您的模板将传递一个Context实例(而不是RequestContext)。要在模板渲染中使用RequestContext,请使用render()快捷方式,该快捷方式与render_to_response()的调用相同,其context_instance参数强制使用RequestContext 1}}。

答案 4 :(得分:1)

假设您有这样的文件结构:

YourDjangoProject
├───project
│   ├───__init__.py
│   ├───asgi.py
│   ├───settings.py
│   ├───urls.py
│   └───wsgi.py
├───.env
├───manage.py
└───db.sqlite3

1) 在任何地方,创建一个 context_processors.py 文件

我将在项目文件夹中创建一个(使用 settings.py):

YourDjangoProject
└───project
    ├───...
    └───context_processors.py

2) 在 context_processors.py 中创建一个函数,它接受一个 HttpRequest 对象作为参数并返回一个字典

上下文处理器只是一个函数,它接受一个 HttpRequest 对象作为参数并返回一个字典。

像这样:

# project/context_processors.py

def site_email(request):
    return {'site_email': 'example@gmail.com'}

3) 将此添加到 context_processors 中的 settings.py 设置中(出于安全原因,位于底部)

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'config' / 'templates'],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'project.context_processors.site_email',  # <- New context processor here
            ],
        },
    },
]

现在,您将能够访问整个网站中每个 django 模板上的“site_email”模板变量。

快乐编码!