Django基础:全局上下文处理器Context Processor

发布于 2020-12-02  723 次阅读


context_processors

中文名:全局上下文处理器,主要用于django在渲染模板(template)传递需要全局使用的变量,比如网站的名字,购物网站中购物车等。

一般应用于setting.py中TEMPLATES

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, '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',
            ],
        },
    },
]

属于RequestContext,是Django一个特殊的Context类,django.template.RequestContext其行为与普通类 略有不同django.template.Context。

1. 第一个区别是它以a HttpRequest作为第一个参数。例如:

c = RequestContext(request, {
    'foo': 'bar',
})

2. 第二个区别是,根据引擎的context_processors配置选项,它会自动用几个变量填充上下文。

context_processors是可调用项的列表,称为上下文处理器,它们以请求对象为参数,并返回要合并到上下文中的项的字典。在默认生成的设置文件中,默认模板引擎包含以下上下文处理器:

[
    'django.template.context_processors.debug',
    'django.template.context_processors.request',
    'django.contrib.auth.context_processors.auth',
    'django.contrib.messages.context_processors.messages',
    ]

此外,还会默认启用 django.template.context_processors.csrf,这是管理员和其他contrib应用程序所需的与安全性相关的上下文处理器,并且在意外配置错误的情况下,会故意对其进行硬编码,并且无法在该context_processors选件中将其关闭。

依次应用每个处理器。这意味着,如果一个处理器将一个变量添加到上下文中,而第二个处理器添加一个具有相同名称的变量,则第二个将覆盖第一个。

内置的模版上下文处理器

这是每个内置处理器的功能:

django.contrib.auth.context_processors.auth

auth()

如果启用了此处理器,则每个处理器都RequestContext将包含以下变量:

  • user- auth.User代表当前登录用户的AnonymousUser实例(如果客户端未登录,则为实例)。
  • perms-的实例 django.contrib.auth.context_processors.PermWrapper,代表当前登录用户所拥有的权限。

django.template.context_processors.debug

debug()

如果启用了此处理器,则每个RequestContext变量都将包含这两个变量-但前提是您的DEBUG设置设为,True并且请求的IP地址(request.META['REMOTE_ADDR'])位于 INTERNAL_IPS设置中:

  • debug- True。您可以在模板中使用它来测试您是否处于DEBUG模式。
  • sql_queries- 词典列表,表示到目前为止在请求期间发生的每个SQL查询以及花费的时间。该列表按数据库别名和查询顺序排序。它是在访问时延迟生成的。{'sql': ..., 'time': ...}

django.template.context_processors.i18n

i18n()

如果启用了此处理器,则每个处理器RequestContext将包含以下变量:

  • LANGUAGES- LANGUAGES设定值。
  • LANGUAGE_BIDI- True如果当前语言是从右到左的语言,例如希伯来语,阿拉伯语。False如果是从左到右的语言,例如英语,法语,德语。
  • LANGUAGE_CODE- request.LANGUAGE_CODE(如果存在)。否则,LANGUAGE_CODE设置的值。

请参阅i18n模板标签以获取生成相同值的模板标签。

django.template.context_processors.media

如果启用了此处理器,则每个处理器RequestContext都将包含一个变量 MEDIA_URL,提供MEDIA_URL设置值。

django.template.context_processors.static

static()

如果启用了此处理器,则每个处理器RequestContext都将包含一个变量 STATIC_URL,提供STATIC_URL设置值。

django.template.context_processors.csrf

该处理器添加csrf_token模板标记所需的令牌,以防止跨站点请求伪造。

django.template.context_processors.request

如果启用了此处理器,则每个处理器RequestContext都将包含一个变量 request,即current HttpRequest。

django.template.context_processors.tz

tz()

如果启用了此处理器,则每个处理器RequestContext都将包含一个变量 TIME_ZONE,提供当前活动时区的名称。

django.contrib.messages.context_processors.messages

如果启用了此处理器,则每个处理器都RequestContext将包含以下两个变量:

  • messages-通过消息框架设置的消息列表(以字符串形式)。
  • DEFAULT_MESSAGE_LEVELS–消息级别名称到其数值的映射 。

编写您自己的上下文处理器

接下来我们来看一个具体例子。我们需要向所有模板传递一个叫site_name的全局变量以便在所有模板中直接使用 {{ site_name }}输出站点名称,我们可以在blog(应用名)的目录下新建context_processors.py,新增如下代码:

现在我们需要向所有模版传递一个全局变量:SITE_NAME(网站名字),方便在所有模板模版中直接使用{{SITE_NAME}} 表示网站名称,假设我们的应用名字:blog,在应用目录下新建一个context_processors.py,新增代码如下:

# blog/context_processors.py

from django.conf import settings

def get_global_name(request):
    return {'SITE_NAME': settings.SITE_NAME,}

然后在setting.py文件新增代码如下:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, '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',
                 # 自定义全局上下文处理器
                'blog.context_processors.global_site_name',  
            ],
        },
    },
]

注意模板中全局变量与本地变量的优先级

全局上下文处理器提供的变量优先级高于单个视图函数给单个模板传递的变量。这意味着全局上下文处理器提供的变量可能会覆盖你视图函数中自定义的本地变量,因此请注意避免本地变量名与全局上下文处理器提供的变量名称重复。这些变量名包括perms, user和debug等等。

如果你希望单个视图函数定义的变量名覆盖全局变量,请使用以下强制模式:

from django.template import RequestContext

high_priority_context = RequestContext(request)
high_priority_context.push({"name": "Jack"})

转载自:http://www.chenxm.cc/article/1082.html


一名测试工作者,专注接口测试、自动化测试、性能测试、Python技术。