7-模板系统
配置
(1)在总项目的settings.py中的TEMPLATES指定可用的模板
(2)创建Template对象,并提供字符串形式的模板代码
(3)调用Template对象的render方法,并传入字典上下文(Context)
模板后端的配置问题
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates',#指定模板引擎类的python路径 'DIRS': [os.path.join(BASE_DIR, 'templates')],#指定模板文件的存放路径 'APP_DIRS': True,#模板引擎会在已安装应用的templates子目录中查找 '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', 'django.contrib.auth.context_processors.auth',#用来在模板中访问用户和权限的上下文处理器 'django.contrib.messages.context_processors.messages',#用来支持消息应用的上下文处理器 ], }, }, ]
Template
from django.template import Template >>>Template("This is {{project}}")
Context
>>> from django.template import Context >>> b=Context({'project':'abc'}) >>> b['project'] 'abc'
render
>>> Template("this is {{project}}").render(Context({'project':'abcd'})) 'this is abcd'
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>templates</title> </head> <body> <h1>Hello,I am is {{ project }}</h1> </body> </html>
views.py
from django.template.loader import get_template def projecthtml(request): t = get_template('firstapp/temp.html')#获取模板,从文件系统中加载模板,只需要传递模板路径 html = t.render({'project':'诺言'})#render传递的是字典,不是Context对象 return HttpResponse(html)
path('html/temp/',views.projecthtml)
再次改写
from django.template.loader import get_template def projecthtml(request): #再次改写 return render(request,'firstapp/temp.html',{'project':'诺言丶诺言'})
render方法的含义: def render(request,template_name,context=None,content_type=None,status=None,using=None) content=loader.render_to_string(template_name,context,request,using=using) return HttpResponse(content,content_type,status)
RequestContext和上下文处理器
与普通的Context相比 (1)实例化需要一个HttpRequest对象,并作为第一个参数 (2)根据模板引擎配置的context_processors自动填充上下文变量
#处理器 def procontext(request): return {'project':'诺言'}#这里使用了HttpRequest类型的参数 from django.template import Template, RequestContext def prorescon(request): t = Template('<h1>{{project}},{{user.username}}</h1>')#显示当前登录的用户 html=t.render(RequestContext(request,processors=[procontext])) return HttpResponse(html)
将处理器加入全局Templates

再次改写之前的方法,将render中的context去掉
def projecthtml(request): #再次改写 return render(request,'firstapp/temp.html')
改写之前的html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>templates</title> </head> <body> <h1>Hello,I am is {{ user.username }},{{ project }}</h1> </body> </html>

模板语法
模板变量与替换规则
变量可以使任意字母、数字和下划线的组合,但是变量中不可以有空格或者标点符号
(1)字典查询{{a.b}}查询a['b']
(2)属性查询{{a.b}}查询a.b
(3)方法调用{{a.b}}查询a.b()
(4)数字索引查询{{a.1}}查询a[1]
1、字典查询
>>> from django.template import Template,Context >>> t = Template('hello:{{user.username}}') >>> user = {'username':'战神'} >>> c = Context({'user':user}) >>> t.render(c) 'hello:战神'
2、属性查询
>>> from django.template import Template,Context >>> import datetime >>> d=datetime.date(2019,12,8) >>> t=Template('time:{{date.year}}') >>> c=Context({'date':d}) >>> t.render(c) 'time:2019'
3、方法调用
>>> class A: ... def x(self): ... return 'django' ... def y(self,v='A的y'): ... return v ... y.alters_data = True #设置方法不被调用
...
>>> tem=Template('hello:{{a.x}},{{a.y}}') >>> text = Context({'a':A()}) >>> tem.render(text) 'hello:django,A的y'
当有异常时,可定义一个类
class hideException(Exception): silent_variable_failure = True #调用这个方法时则不会抛出异常
4、数字索引查询
>>> te=Template('hello:{{item.0}},{{item.1}}') >>> co=Context({'item':['我是0','我是1']}) >>> te.render(co) 'hello:我是0,我是1'
模板标签
if标签
语法结构如下:if和endif必须是成对存在的
{% if 表达式 %}
。。。。。。。。
{% elif 表达式 %}
。。。。。。。。
{% else %}
。。。。。。。。
{% endif %}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>templates</title> </head> <body> {% if user.username == 'xym' %} <h1>Hello,I am is {{ user.username }},{{ project }}</h1> {% elif user.username == '战神'%} <h1>Welcome,I am is {{ user.username }},{{ project }}</h1> {% endif %} </body> </html>


for标签
语法结构如下:for和endfor必须成对存在
{% for 项 in 数组 %}
。。。。。。。。。。。
{% empty %}当列表不存在时显示empty下的内容
。。。。。。。。。。。
{% endfor %}
def projecthtml(request, username): user = {'username': username} # 再次改写 return render(request, 'firstapp/temp.html', {'user': user, 'users': [ {'name': '诺言', 'password': '123456'}, {'name': '战神', 'password': '123456'}, {'name': '诺言', 'password': '123456'}, {'name': '战神', 'password': '123456'}, {'name': '诺言', 'password': '123456'}, {'name': '战神', 'password': '123456'}, ]})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>templates</title> </head> <body> {% if user.username == 'xym' %} <h1>Hello,I am is {{ user.username }},{{ project }}</h1> {% elif user.username == '战神' %} <h1>Welcome,I am is {{ user.username }},{{ project }}</h1> {% endif %} <table border="1"> <tr> <th>序号</th> <th>姓名</th> <th>密码</th> </tr> {% for item in users %} <tr> <td>{{ forloop.counter }}</td> {% comment %}计数,标记当前是第几个元素{% endcomment %} <td>{{ item.name }}</td> <td>{{ item.password }}</td> </tr> {% empty %} <tr> <td>无用户</td> <td>无密码</td> </tr> {% endfor %} </table> </body> </html>
forloop还有几个属性:
(1)counter0:从0开始计数
(2)counter:从1开始计数
(3)revcounter:用来标识循环中剩余项,最后一次表达为1
(4)revcounter0:最后一次表达为0
(5)first:如果当前元素为第一个元素,为True,其余为False
(6)last:如果元素为最后一个元素,为True,其余为False
(7)parentloop:用于调用父级元素的forloop
url标签
语法结构如下:
{% url 视图的命名空间:视图函数 参数列表 %}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Topic列表</title> </head> <body> {% block content %}{% comment %}暂时还不知道是干嘛的,后面会详细讲{% endcomment %} <h2>Topics</h2> <ul> {% for topic in object_list %} {% comment %}对传过来的modellist做each循环{% endcomment %} <li> <a href="{% url 'first:topic-detail' topic.id %}">{% comment %}将循环出来的id通过反向解析使用topic详情获取topic详情{% endcomment %} {{ topic.title }}</a>{% comment %}这里放每一个话题title{% endcomment %} </li> {% endfor %} </ul> {% endblock %} </body> </html>
comment标签
语法结构如下:
{% comment %}注释{% endcomment %}
变量是否相等的标签
{% ifuqeal v1 v2 %}True
。。。。。。。。。。。
{% else %}False
。。。。。。。。。。。
{% endifuqeal %}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>templates</title> </head> <body> {% ifequal user.username 'xym' %} <h1>Hello,I am is {{ user.username }},{{ project }}</h1> {% else %} <h1>Welcome,I am is {{ user.username }},{{ project }}</h1> {% endifequal %} <table border="1"> <tr> <th>序号</th> <th>姓名</th> <th>密码</th> </tr> {% for item in users %} <tr> <td>{{ forloop.counter }}</td> {% comment %}计数,标记当前是第几个元素{% endcomment %} <td>{{ item.name }}</td> <td>{{ item.password }}</td> </tr> {% empty %} <tr> <td>无用户</td> <td>无密码</td> </tr> {% endfor %} </table> </body> </html>
自定义标签
准备
(1)在应用下创建一个python包templatetags,并创建custom_tags.py文件
(2)在settings中的INSTALLED_APPS将应用加入
#!/usr/bin/env python # -*- coding:utf-8 -*- from django import template register=template.Library()#一个有效的标签库必须有一个模板层变量register
@register.simple_tag(takes_context=True,name='index')#takes_context访问上下文字典,name此标签的名字
def prefix_tag(cur_str):
return 'hello %s'%(context['first'],cur_str)
自定义标签的使用,使用load标签声明:{% load custom_tags %}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>自定义</title> </head> <body> {% load custom_tags %}{% comment %}加载库标签{% endcomment %} {% index '诺言' %} <h1>{{ hello }}</h1><!--应用变量的形式--> </body> </html>

浙公网安备 33010602011771号