上下文处理器是可以返回一些数据,在全局模板中都可以使用。比如登录后的用户信息,在很多页面中都需要使用,那么我们可以放在上下文处理器中,就没有必要在每个视图函数中都返回这个对象。
在settings.TEMPLATES.OPTIONS.context_processors
中,有许多内置的上下文处理器。
django.template.context_processors.debug
:增加一个debug
和sql_queries
变量。在模板中可以通过他来查看到一些数据库查询。django.template.context_processors.request
:增加一个request
变量。这个request
变量也就是在视图函数的第一个参数。{{ request.path }} 查看路径
django.contrib.auth.context_processors.auth
:Django
有内置的用户系统,这个上下文处理器会增加一个user
对象。所以在上下文处理等时添加键不能为userdjango.contrib.messages.context_processors.messages
:增加一个messages
变量。 ```pythonviews.py
from django.contrib import message
def index(request): …
# messages.add_message(request,messages.INFO,'用户密码不存在')
messages.info(request, '用户密码不存在') #messages作为上下文可以在模板中使用
....
return redirect(reverse('signin'))
```html
{% for message in messages %}
<td>
{{ message }}
</td>
{% endfor %}
django.template.context_processors.media
:在模板中可以读取MEDIA_URL
。
比如想要在模板中使用上传的文件,那么这时候就需要使用settings.py
中设置的MEDIA_URL
来拼接url
。
```python# setting.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'medias') # 要在当前项目路径下添加一个目录medias
MEDIA_URL = '/media/' # url访问地址
urls.py
from django.urls import path from django.conf.urls.static import static from django.conf import settings
urlpatterns = [ path(‘’, views.index), ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```html
<img src="{ MEDIA_URL }abc.png" alt="">
{# 如果文件夹medias下面就有一个abc.png #}
django.template.context_processors.static
:在模板中可以使用STATIC_URL
。django.template.context_processors.csrf
:在模板中可以使用csrf_token
变量来生成一个csrf token
。MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', # 开启csrf
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
<input type="hidden" name-"csrfmiddlewaretoken" value={{ csrf_tokon }}>
{# 这样在开启csrf中间件也不会被拒绝 #}
在表单中使用{{% csrf_tokon %}}
和上述代码作用一样
如果在head头要用到csrf_tokon,则只能使用{{csrf_tokon}}
而不是{%csrf_tokon %}
自定义上下文处理器
有时候我们想要返回自己的数据。那么这时候我们可以自定义上下文处理器。
自定义上下文处理器的步骤如下:
- 你可以根据这个上下文处理器是属于哪个
app
,然后在这个app
中创建一个文件专门用来存储上下文处理器。比如context_processors.py
。或者创建一个Python包
,用来存储所有的上下文处理器。 - 在定义的上下文处理器文件中,定义一个函数
- 这个函数只有一个
request
参数。这个函数只有一个request
参数。 - 这个函数中处理完自己的逻辑后,把需要返回给模板的数据,通过字典的形式返回。
- 如果不需要返回任何数据,那么也必须返回一个空的字典。这个函数中处理完自己的逻辑后,把需要返回给模板的数据,通过字典的形式返回。
- 如果不需要返回任何数据,那么也必须返回一个空的字典。 ```shell from .models import User
- 这个函数只有一个
def front_user(request): user_id = request.session.get(“user_id”) # 这里的user_id存储的时候是登陆找到的用户id context = {} if user_id: try: user = User.objects.get(pk=user_id) context[‘front_user’] = user # front_user对应的是一个模型对象 except: pass return context
3. `setting.py`中设置该文件位置
```python
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',
'front.context_processer.front_user', # 这里添加路径
],
},
},
]
使用
<ul class="nav navbar-nav navbar-right"> {# 这里是bootstrap模型设置的 #}
{% if front_user %}
<li><a href="/">{{ front_user.username }}</a></li> {# front_user就是上面设置的全局的上下文,username是字段 #}
{% else %}
<li><a href="{% url 'signin' %}">登陆</a></li>
<li><a href="{% url 'register' %}">注册</a></li>
{% endif %}
</ul>