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

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

有人告诉我,编写自己的上下文处理器是做到这一点的最佳方式,但我遇到了一些问题。

我的设置文件如下所示

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 _ 處理器”的模块和一个名为“ 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")
46000 次浏览

The context processor you have written should work. The problem is in your view.

Are you positive that your view is being rendered with RequestContext?

For example:

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

The view above will not use the context processors listed in TEMPLATE_CONTEXT_PROCESSORS. Make sure you are supplying a RequestContext like so:

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

According to the django docs you can use render as a shortcut instead of render_to_response with the context_instance argument:

Alternatively, use the render() shortcut which is the same as a call to render_to_response() with a context_instance argument that forces the use of a RequestContext.

If you’re using Django’s render_to_response() shortcut to populate a template with the contents of a dictionary, your template will be passed a Context instance by default (not a RequestContext). To use a RequestContext in your template rendering, use the render() shortcut which is the same as a call to render_to_response() with a context_instance argument that forces the use of a RequestContext.

Since Django 1.8 you register your custom context processors like this:

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',
],
},
},
]

assuming your context processor is in app www in context_processors.py

Let's say you have a file structure like this:

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

1) Anywhere, create a context_processors.py file

I'll create one in the project folder (with settings.py):

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

2) Create a function in context_processors.py that accepts a HttpRequest object as an argument and returns a dictionary

A context processor is just a function that accepts an HttpRequest object as an argument and returns a dictionary.

Like this:

# project/context_processors.py


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

3) Add this to your context_processors setting in settings.py (at the bottom for security reasons)

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
],
},
},
]

Now you'll be able to access the 'site_email' template variable on every single django template across your whole site.

Happy coding!