1.在模板中处理上下文处理
上下文就是一系列模板变量和相应的值。模板使用上下文填充变量,放到标签里显示在页面。在 Django 中,上下文使用 django.template 模块中的 Context 类表示。 它的构造方法接受一个可选参数:一个字典,把变量名映射到值上。“填充”模板的方式是,在 Template 对象 上调用 render() 方法,并传入上下文,如我们前面写的视图函数classnotice:
from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/')
def classnotice(request):
print(request.GET)
now=datetime.datetime.now()
context={}
context['student_list']=Student.objects.all().order_by('-score')
context['teacher']='王重阳'
context['now']=now
return render(request,'class3.html',context=context,status=200)
上下文变量查找:
模板系统能优雅处理很多复杂的数据结构,例如列表、字典和自定义的对象。遍历 Django 模板 中复杂数据结构的关键是点号 "." 。 点号可以访问字典的键、属性、方法或对象的索引。
如我们在class3.html的标签中用点号 . 访问student的具体属性
{% extends "base.html" %}
{% block title %}武侠三班的小窝 {% endblock %}
{% load my_tags %}
{% block main %}
<h1>通知</h1>
<p>本次中期比武,{{ student_list.0.name }}获得了第一名</p>
<p>获得优秀的同学还有{{student_list.1.name}}、{{student_list.2.name}}、{{student_list.3.name}}等</p>
<p>希望其他同学以他们为榜样,苦练武功,争取下次比武取得好成绩</p>
<ul>
{% for s in student_list %}
{% if s.sex == 'male' %}
<li>{{ s.name }}大侠的成绩为 {% chengfa s.score 10 %}</li>
{% else %}
{% chufa s.score 10 as jg %}
<li>{{ s.name }}女侠的成绩为 {{jg}} </li>
{% endif %}
{% endfor %}
</ul>
<p>落款:你们尊敬的老师<br />{{ teacher }}</p>
<p>日期: {{ now|date:"D d M Y" }} </p>
{% endblock %}
注意,跟Python中不同的是,这里无论字典还是列表,都是用 . 来获取值。
2.上下文处理器
每个视图都可以返回自己的数据,但是有些数据全局都需要使用,比如用户信息等,这时候如果每个视图函数都来获取一遍用户信息再传给标签,就会显得繁琐。
这时候就可以用到Django的上下文处理器,一些反复用到的数据可以放在上下文处理器中,在全局模板中都可以使用,就没有必要在每个视图函数中都返回这个对象。
2.1自定义上下文处理器:
上下文处理器的接口十分简单,它就是普通的 Python 函数,有一个参数,是一个 HttpRequest 对象,返回一 个字典,用于添加到模板上下文中。上下文处理器必须返回一个字典。下面是自定义处理器的
比如我们现在想把用户名放在上下文处理器中,在views.py中写一个视图函数:
def custom_name(request):
# 一个上下文处理器,提供 'app'、'user' 和 'ip_address'
return {
'yonghu': request.user.name, #这里注意不要再用user作变量名,容易跟系统的user重名
}
然后在setting里面设置为全局变量
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',
'newweb.views.custom_name',
],
},
},
]
然后我们直接在base.html中引用这个上下文:
<div class="header">
<h1>武侠世界</h1>
<p>武林人士自己的线上江湖</p>
<p>欢迎你,{{yonghu}}</p>
{% block title %}
武侠二班主页
{% endblock title %}
</div>
注意这里不需要再引用函数名了,直接用函数定义的变量名 yonghu,就可以获取到这个值
2.2 关于自定义上下文处理器的tips:
• 上下文处理器应该尽量负责较少的功能。处理器易于合用,因此应该把功能分成逻辑片段,供以后复用。
• TEMPLATE_CONTEXT_PROCESSORS 中列出的各个上下文处理器在那个设置文件管辖的每个模板中都可用,因此应该为变量挑选不易与模板自身设定的变量冲突的名称。因为变量区分大小写,所以让处理器提供的变量都使用大写不失为一个好主意。
• 自定义的上下文处理器可以放在代码基的任何位置。Django 只关心TEMPLATES 设置中的 'context_processors' 选项或者 Engine 的 context_processors 参数(直接使用 Engine 时)有没有指向你的上下文处理器。尽管如此,约定的做法是把上下文处理器保存在应用或项目中一个名为 context_processors.py 的文件中。
3.Django内置上下文处理器:
Django内置了一些上下文处理器,刚刚我们设置的setting表中也列出了默认启动的几个
3.1 auth
django.contrib.auth.context_processors.auth
启用这个处理器后,RequestContext 中将包含下述变量:
• user:auth.User 的实例,表示当前登录的用户(如未登录,是 AnonymousUser 实例)。
• perms:django.contrib.auth.context_processors.PermWrapper 实例,表示当前登录用户拥有的权限。
3.2 debug
django.template.context_processors.debug
启用这个处理器后,RequestContext 中将包含下面两个变量,但前提是 DEBUG 设置的值是 True,而且 INTERNAL_IPS 设置中包含请求的 IP 地址(request.META['REMOTE_ADDR']):
• debug:True。可以在模板中测试是否在 DEBUG 模式中。
• sql_queries:{'sql': …, 'time': …} 字典构成的列表,表示处理请求的过程中执行的 SQL 查询及其 用时。列表中的值按查询的执行顺序排列,在访问时惰性生成。
3.3 i18n
django.template.context_processors.i18n
启用这个处理器后,RequestContext 中将包含下面两个变量:
• LANGUAGES:LANGUAGES 设置的值。
• LANGUAGE_CODE:如果 request.LANGUAGE_CODE 存在,返回它的值;否则返回 LANGUAGE_CODE 设置的值。
3.4 media
django.template.context_processors.media
启用这个处理器后,RequestContext 中将包含 MEDIA_URL 变量,提供 MEDIA_URL 设置的值。
3.5 static
django.template.context_processors.static
启用这个处理程序后,RequestContext 中将包含 STATIC_URL 变量,提供 STATIC_URL 设置的值。
3.6 csrf
django.template.context_processors.csrf
这个处理器添加一个令牌,供 csrf_token 模板标签使用,用于防范跨站请求伪造。
3.7 request
django.template.context_processors.request
启用这个处理器后,RequestContext 中将包含 request 变量,它的值是当前的 HttpRequest 对象。
3.8 messages
django.contrib.messages.context_processors.messages
启用这个处理器后,RequestContext 中将包含下面两个变量:
• messages:消息框架设定的消息列表(里面的值是字符串)。
• DEFAULT_MESSAGE_LEVELS:消息等级名称到数字值的映射。