生命就应该不自量力地还手,直至死方休
目录来了
- 模板介绍
1.1 模板处理
1.2 快捷函数 - 模板语言DTL
2.1 变量
2.2 在模板中调用对象的方法
2.3 标签(9个标签)
2.4 过滤器
2.5 示例
2.5.1 模板
2.5.2 视图函数 - 模板继承
3.1 说明
3.2 三层继承结构
—————————————————————————
1. 模板介绍
作为 Web 框架, Django 提供了模板,可以很便利的动态生成 HTML
模版系统致力于表达外观,而不是程序逻辑
模板的设计实现了业务逻辑(view)与显示内容(template)的分离,一个视图可以使用一个模板也可以供多个视图使用
模板包含
HTML 的静态部分
动态插入内容部分
Django 模板语言,简写 DTL,定义在 django.template 包中
由 startproject 命令生成的 settings.py 定义关于模板的值:
DIRS 定义了一个目录列表,模板引擎按列表顺序搜索这些目录以查找模板源文件
APP_DIRS 告诉模板引擎是否应该在每个已安装的应用中查找模板
常用方式:在项目的根目录下创建 templates 目录,设置 DIRS 值
DIRS=[os.path.join(BASE_DIR,"templates")]
—————————————————————————
1.1 模板处理
Django 处理模板分为两个阶段
Step1 加载:根据给定的标识找到模板后预处理,将它编译好放在内存中返回一个 Template 对象
loader.get_template(template_name),
Step2 渲染:使用 Context 数据对模板插值并返回生成的字符串
Template 对象的 render(RequestContext)方法,使用 context 渲染模板
加载渲染完整代码:
from django.template import loader, RequestContext
from django.http import HttpResponse
def index(request):
tem = loader.get_template('temtest/index.html')
context = {}
return HttpResponse(tem.render(context))
—————————————————————————
1.2 快捷函数
为了减少加载模板、渲染模板的重复代码, django 提供了快捷函数
render_to_string("")
render(request,'模板',context)
from django.shortcuts import render
def index(request):
return render(request, 'temtest/index.html')
—————————————————————————
2.模板语言DTL
模板语言包括
变量
标签 { % 代码块 % }
过滤器
注释{# 代码或 html #}
—————————————————————————
2.1 变量
语法:
{{ variable }}
当模版引擎遇到一个变量,将计算这个变量,然后将结果输出
变量名必须由字母、数字、下划线(不能以下划线开头)和点组成
当模版引擎遇到点("."),会按照下列顺序查询:
字典查询,例如: foo["bar"]
属性或方法查询,例如: foo.bar
数字索引查询,例如: foo[bar]
如果变量不存在, 模版系统将插入'' (空字符串)
—————————————————————————
2.2 在模板中调用对象的方法
在模板中调用方法时不能传递参数
在 models.py 中定义类 HeroInfo
from django.db import models
class HeroInfo(models.Model):
...
def showName(self):
return self.hname
在 views.py 中传递 HeroInfo 对象
from django.shortcuts import render
from models import *
def callMethodInTemplate(request):
hero = HeroInfo(hname='abc')
context = {'hero': hero}
return render(request, 'booktest/detail2.html', context)
应用 urlcof 中添加:
url(r'^callMethodInTemplate/$', views.callMethodInTemplate),
在模板 detail2.html 中调用
{{hero.showName}}
—————————————————————————
2.3 标签(9个标签)
语法:
{ % tag % }
for 标签
循环逻辑: {%for ... in ...%}
注意:
1、 %和{}中间没有空格 { % % }写法是不对的
2、 Django 不支持退出循环操作。 如果想退出,可以让迭代变量仅包含需要迭代的项目。
3、 Django 也不支持 continue 语句,我们无法让当前迭代操作跳回到循环头部。
语法:
{{forloop.counter}}
表示当前是第几次循环
{%empty%}
给出的列表空为或列表不存在时,执行此处
{%endfor%}
范例
{%for item in heroList%}
<div>{{ forloop.counter }}: {{ item.showName }}</div>
<div>当前是第{{forloop.counter}}次循环</div>
{%empty%}
<div>给出的列表为或列表不存在时,执行此处</div>
{%endfor%}
reversed 标签: 使得该列表被反向迭代
{%for item in heroList reversed %}
if 标签
{%if ...%}
逻辑 1
{%elif ...%}
逻辑 2
{%else%}
逻辑 3
{%endif%}
范例
{%if hero.showName == '黄蓉'%}
<div>黄蓉</div>
{%else%}
<div>其他英雄</div>
{%endif%}
注意:
hero.showName == 之间一定要有空格!
如果连在一起写 hero.showName==, 程序会将它们看成了一个整体而报错:
Could not parse the remainder: '=='1'' from 'sort=='1''
逻辑运算符
and 表示两个条件同时满足
or 表示只满足一个条件即可(or 和 and 不可以同时使用)
not 也是合法的
注释标签
多行注释
{% comment %}
多行注释
{% endcomment %}
范例
{% comment %}
This is a
multi-line comment.
{% endcomment %}
单行注释
{# 这是一个注释 #}
范例
This is a {# this is nota comment #}test.
include 标签
加载模板并以标签内的参数渲染
{%include "foo/bar.html" %}
反向生成 url
{ % url 'name' p1 p2 %}
范例
<a href="{% url 'booktest.views.detail' book.id %}">{{ book.btitle }}</a>
csrf_token
这个标签用于跨站请求伪造保护
{ % csrf_token %}
布尔标签
and、 or, and 比 or 的优先级高
其它标签
block、 extends:详见“模板继承”
autoescape:详见“HTML 转义”
—————————————————————————
2.4 过滤器
语法
{ { 变量|过滤器 }}
例如{ { name|lower }},表示将变量 name 的值变为小写输出
管道符号|
应用于过滤器, 通过使用过滤器来改变变量的计算结果
范例
在 if 标签中使用过滤器结合运算符
if list1|length > 1
过滤器链
过滤器能够被“串联” ,构成过滤器链
name|lower|upper
过滤器参数传递
参数使用引号包起来
list|join:", "
设置默认值
default:如果一个变量没有被提供,或者值为 false 或空,则使用默认值,否则使用变量的值value|default:"什么也没有"
date
根据给定格式对一个 date 变量格式化
value|date:'Y-m-d'slicevalue |slice:'10'
详细的过滤器
https://docs.djangoproject.com/en/2.0/ref/templates/builtins/
—————————————————————————
2.5 示例
示例
查询所有英雄信息显示出来,要求奇数行显示为红色,偶数行显示为蓝色
—————————————————————————
2.5.1 模板
模版
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
.red {
color: red;
background-color: white;
}
.blue {
color: blue;
background-color: gray;
}
</style>
</head>
<body>
{% for item in ls %}
{% if item.color == 'red' %}
<div class="red">{{ item.hero.hname }}</div>
{%else%}
<div class="blue">{{ item.hero.hname }}</div>
{%endif%}
{% endfor %}
</body>
</html>
—————————————————————————
2.5.2 视图函数
def getlist(request):
ls = HeroInfo.objects.all()
count = ls.count()
ls1 = []
for i in range(count):
tmp = {}
tmp['hero'] = ls[i]
if i % 2 == 0:
tmp['color'] = 'blue'
else:
tmp['color'] = 'red'
ls1.append(tmp)
context = {'ls':ls1}
return render(request,'colortest.html',context)
—————————————————————————
3.模板继承
模板继承可以减少页面内容的重复定义,实现页面内容的重用
典型应用:网站的头部、尾部是一样的,这些内容可以定义在父模板中,子模板不需要重复定义
block 标签:在父模板中预留区域,在子模板中填充
extends 继承:继承,写在模板文件的第一行定义父模板 base.html
{ %block block_name%}
这里可以定义默认值
如果不定义默认值,则表示空字符串
{ %endblock%}
定义子模板 index.html
{ % extends "base.html" %}
在子模板中使用 block 填充预留区域
{ %block block_name%}
实际填充内容
{ %endblock%}
—————————————————————————
3.1 说明
如果发现在模板中大量的复制内容,那就应该把内容移动到父模板中
如果在模版中使用 extends 标签,它必须是模版中的第一个标签
不能在一个模版中定义多个相同名字的 block 标签
子模版不必定义全部父模版中的 blocks,如果子模版没有定义 block,则使用了父模版中的默认值, 使用可以获取父模板中 block 的内容
为了更好的可读性,可以给 endblock 标签一个名字
{ % block block_name %}
区域内容
{ % endblock block_name %}
—————————————————————————
3.2 三层继承结构
三层继承结构使代码得到最大程度的复用,并且使得添加内容更加简单
如下图为常见的电商页面
1.创建根级模板
名称为“base.html”
存放整个站点共用的内容
<!DOCTYPE html>
<html>
<head>
<title>{%block title%}{%endblock%} 水果超市</title>
</head>
<body>
top--{{logo}}
<hr/>
{%block left%}{%endblock%}
{%block content%}{%endblock%}
<hr/>
bottom
</body>
</html>
2.创建分支模版
继承自 base.html
名为“base_*.html”
定义特定分支共用的内容
定义 base_goods.html
{%extends 'temtest/base.html'%}
{%block title%}商品{%endblock%}
{%block left%}
<h1>goods left</h1>
{%endblock%}
定义 base_user.html
{%extends 'temtest/base.html'%}
{%block title%}用户中心{%endblock%}
{%block left%}
<font color='blue'>user left</font>
{%endblock%}
定义 index.html,继承自 base.html,不需要写 left 块
{%extends 'temtest/base.html'%}
{%block content%}
首页内容
{%endblock content%}
3.为具体页面创建模板,继承自分支模板
定义商品列表页 goodslist.html
{%extends 'temtest/base_goods.html'%}
{%block content%}
商品正文列表
{%endblock content%}
定义用户密码页 userpwd.html
{%extends 'temtest/base_user.html'%}
{%block content%}
用户密码修改
{%endblock content%}
4.视图调用具体页面,并传递模板中需要的数据
首页视图 index
logo='welcome to MyMoon YouHeart'
def index(request):
return render(request, 'temtest/index.html', {'logo': logo})
商品列表视图 goodslist
def goodslist(request):
return render(request, 'temtest/goodslist.html', {'logo': logo})
用户密码视图 userpwd
def userpwd(request):
return render(request, 'temtest/userpwd.html', {'logo': logo})
5.配置 url
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^list/$', views.goodslist, name='list'),
url(r'^pwd/$', views.userpwd, name='pwd'),
]
感谢语
一口气连着写了好几篇文章,哎!没有期待就没有未来!一首有没有人曾告诉你在我耳朵里逍遥了一上午了!我听见有人欢呼,有人在哭泣!!!
网友评论