django学习笔记之模板层
使用模板层之前已经学习过替换法, 将字符串直接在某个位置进行替换, 然后发送到前端渲染
def index(request):
ctime = datetime.datetime.now()
res = '<a href="http://www.baidu.com">点我 <p>时间: %s</p></a>'% ctime
return HttpResponse(res)
这样写的代码粘合性很强, 当要修改某段代码时需要查找的范围会相应复杂, 因此 基于这些原因, 将页面设计和python的代码分离开会更好且容易维护, 我们需要使用Django的模板系统实现这种模式,
Python的模板: HTML代码 + 模板语法
views.py
def index(request):
ctime = datetime.datetime.now()
return render(request, 'index.html', context={'ctime': ctime})
HTML
<body>
<h1>index</h1>
现在时间是: {{ ctime }}
</body>
重点:
模板语法
变量: {{变量名}}
- 深度查询 用句点符
- 过滤器
标签: {% %}
- 模板语法之变量
在Django模板中遍历复杂数据结构的关键字是句点符, 语法: {{ 变量. 值 }} 值可有可无
view.py
def index(request):
ctime = datetime.datetime.now()
str = '这是字符'
list = ["这是列表"]
dict = {"这是字典":111}
set= {"这是集合"}
tuple = ("这是元组")
float = 3.4
age = 18
def func():
return "这个是函数"
class T:
def __init__(self, name):
self.name = name
def prin(self):
return self.name
name = T("chen")
res = name.prin()
# return HttpResponse(res)
# 有两种传参方式, 一种是全写, 一种 locals()
# 方法1: 写全
return render(request, 'index.html', context={
'ctime': ctime,"str":str,"list":list,
"dict":dict,"set":set,"tuple":tuple,
"float":float,"int":age,"func":func,"class":res})
# 方法二: 直接接受所有参数进行传递
return render(request, 'index.html', locals())
html中
<h1>index</h1>
现在时间是: {{ ctime }}<br>
{{ str }}<br>
{{ list }}<br>
{{ dict }}<br>
{{ set }}<br>
{{ tuple }}<br>
{{ float }}<br>
{{ int }}<br>
{{ func }}<br>
{{ class }}<br>
</body>
- 解决后端发送数据不被前端识别
#当后端发送一段 HTML字符串过来时, 用该使用模板进行渲染, 然而Django把这个给屏蔽了, 需要自己转换, 使用mark_safe()
没加mark_save前
def index(request):
res = '<a href="http://www.baidu.com">点我</a>'
return render(request, 'index.html', context={"ctime":res})
前端打印结果 ` <a href="http://www.baidu.com">点我</a> `
加上后, 需要导入模块
def index(request):
res = '<a href="http://www.baidu.com">点我</a>'
from django.utils.safestring import mark_safe
link = mark_safe(res)
return render(request, 'index.html', context={"ctime":link})
html代码
<h1>index</h1>
现在时间是 <h1>{{ ctime }}</h1>
</body>
- 深度查询之句点符
列表, 字典 多层嵌套等方法
views.py
def index(request):
list = [1,2,3,[4,5,[6,7]]]
dic = {"name":"chen", "gender":"male"}
return render(request, 'index.html', context={"list":list,"dic":dic})
html
<body>
<h1>index</h1>
列表取值{{ list.0 }} 使用 .数字方式取值
列表取值{{ list.5.0 }} 可以连续的点下去
字典取值{{ dic.name }} .字典的键取值
</body>
-
c常用过滤器
语法
{{ obj|filter_name:param}} 变量名|过滤器名:变量
注意:冒号后面不能加空格
-
default
如果一个变量为False, 或者为空, 给定义的变量默认值, 如果不是则正常显示{{ value|default:"nothing" }}
-
length
统计值的长度, 统计字符串或列表{{ value|length }}
-
filesizeformat
将文件大小 bytes 格式转化为可读模式,如:5kB, 10GB
等{{ value|filesizeformat }}
-
date
将日期格式转化为好看的格式{{ value|date:"Y-m-d" }}
-
slice
切片取值, 跟python字符串切片一模一样{{ value|slice:"2:-1" }}
-
truncatechars
如果字符串字符过多, 指定切除长度, 指定长度会被留下, 其余全被忽略不显示需要传参数 结尾(…) 点也包含在参数内
{{ value|truncatechars:9 }}
-
safe
Django的模板中会出现标签和js语法自动转换为可读样式, 为了安全起见, Django把全部的都以字符串格式显示, 如果想要转换自行使用safe格式转换, 这是为了防止xss攻击, 与前面的mark_safe一样的使用方式, 其实两个都是继承了safe的类
如:
value = "<a href=> 点击 </a>"
{{ value|safe}}
还有很多过滤器, 自行搜索了解
-
-
过滤器的使用例子
views.py def index(request): ctime = datetime.datetime.now() str = "I guess you never really know what's going on inside a person's head." size = 123455 return render(request, 'index.html', context={"ctime":ctime,"str":str,"size":size}) 1. default 默认值 <body> <h1>index</h1> 当变量不存在或存在没有值时会使用默认值 默认值; {{ str|default:"没有值" }} {{ ss|default:"没有值" }} ss值不存在在页面上显示默认值 </body> 2. length 统计长度 <body> <h1>index</h1> 统计长度; {{ str|length }} </body> 3. filesizeformat 统计文件大小 <body> <h1>index</h1> 文件大小: {{ size|filesizeformat }} </body> 4. date 日期格式 <body> <h1>index</h1> 现在时间是: {{ ctime|date:"Y-m-d" }} </body> 5. slice 切片 <body> <h1>index</h1> 切片在 2-10之间的值: {{ str|slice:"2:10" }} </body> 6. truncatechars 摘要, 省略 <body> <h1>index</h1> 摘要: {{ str|truncatechars:20 }} </body>
-
模板语法在标签
for循环, 列表循环, 字典循环, 循环列表对象
for循环模板 {% for foo in list %} {{ foo }} {% endfor %} 循环为空 {% for foo in ll5 %} <p>foo.name</p> {% empty %} <p>空的</p> {% endfor %} forloop的使用 forloop所有属性 {#'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 4, 'revcounter0': 3, 'first': True, 'last': False}#} counter: 序号开始值 revcounter: 倒叙 first: 第一个值 last: 最后一个值 html文件 <body> <h1>index</h1> {% for foo in lists %} <p>{{ foo }}</p> {% empty %} <p>空</p> {% endfor %} </body> views.py def index(request): ctime = datetime.datetime.now() list = [1,2,34,5,6,7,8] return render(request, 'index.html', context={"ctime":ctime,"list":list}) 也可以结合if判断使用, 用法跟python一样
-
if判断
用法:后端代码就不多粘贴了, 自行解决, html {% if 条件 %} <p>{{ 表达式 }}</p> {% elif 条件 %} <p>{{ 表达式 }}</p> {% else %} {{ 表达式 }} {% endif %} {% if name %} <a href="">hi {{ name }}</a> <a href="">注销</a> {% else %} <a href="">请登录</a> <a href="">注册</a> {% endif %} {#还有elif#}
句点符 {{ dic.name.upper }}
-
with的使用
{% with ll2.0.name as n %} {{ n }} {% endwith %} {% with total=business.employees.count %} {{ total }} employee{{ total|pluralize }} {% endwith %} 不要写成as
csrf_token
{% csrf_token%}
这个标签用于跨站请求伪造保护
-
自定义过滤器
1 自定义过滤器 -第一步:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag -第二步:在app中创建templatetags包(包名只能是templatetags,不能改) -第三步:在包内,新建py文件(如:my_tags.py) -第四步:写代码(过滤器) from django import template register = template.Library() @register.filter def my_upper(value): return value.upper() -第五步使用:(模板),先load,再使用 {% load my_tags %} {{ 'aa'|my_upper }} 2 自定义标签 -第一步:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag -第二步:在app中创建templatetags包(包名只能是templatetags,不能改) -第三步:在包内,新建py文件(如:my_tags.py) -第四步:写代码(过滤器) from django import template register = template.Library() @register.simple_tag def my_csrf(): import uuid res=uuid.uuid4() return mark_safe('<input type="hidden" name="csrfmiddlewaretoken" value="%s">'%res) -第五步使用:(模板),先load,再使用 {% load my_tags %} {% my_csrf %} {% my_tag 1 3 4 %}
-
模板导入与继承
1 模板的导入 -第一步:新建一个 xx.html,把好看的模板写入 <div class="panel panel-danger"> <div class="panel-heading"> <h3 class="panel-title">重金求子</h3> </div> <div class="panel-body"> 详情点击:<a href="http://www.baidu.com">疯狂点我</a> </div> </div> -第二步:再你想用的地方 {% include 'xx.html' %} 2 模板的继承(母版) -第一步:写一个母版,写空盒子 {% block top %} {% endblock %} -第二步:某个页面要使用母版,引入,扩写盒子 {% extends 'base.html' %} {% block top %} index页面 {% endblock %}
-
静态文件相关
# 三种方式 第一种: <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> 第二种: {% load static %} <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}"> 第三种: {% load static %} <link rel="stylesheet" href="{% get_static_prefix %}bootstrap/css/bootstrap.min.css"> # 特殊用法 {% load static %} {% static "images/hi.jpg" as myphoto %} <img src="{{ myphoto }}"></img> {% load static %} {% get_static_prefix as static %} <img src="{{ static }}images/hi.jpg" alt="Hi!" />
-
inclusion_tag的使用
# 可以生成一片模板中的代码块 # 使用:5步 -第一步:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag -第二步:在app中创建templatetags包(包名只能是templatetags,不能改) -第三步:在包内,新建py文件(如:my_tags.py) -第四步:写代码(inclusion_tag) # inclusion_tag,传一个模板文件 @register.inclusion_tag('left.html') def left(num): # dic={0:第0页,1:第1页,2:第2页} dic = {i: '第%s页' % i for i in range(num)} # 固定返回的必须是字典 print(dic) return {'data': dic} @register.inclusion_tag('beautiful.html') def beautiful(title, url): return {'title': title, 'url': url} -第五步使用:(模板),先load,再使用 {% load my_tags %} {% left 5%} {% beautiful '名字' '地址'%} # 它跟tag有什么不同? -tag需要再代码中写html的东西 -inclusion_tag代码跟模板分离