Django--模板系统
模板渲染
1.基础变量渲染
关于模板渲染你只需要记两种特殊符号(语法):
变量相关的用{{ 变量 }} 和 逻辑相关的用{% 逻辑 %}
urls.py
from app01 import views
urlpatterns = [
url(r'^home/', views.home),
]
views.py
from django.shortcuts import render
def home(request):
name = 'jia'
age = 18
hobby = ['王姑娘','与姑娘']
info = {
'username':'老白',
'password':'123'
}
class A:
def __init__(self):
self.xx = 'xxxx'
def show_phone(self):
return 120
a = A() #类实例化
data = {
'name':name,
'age':age,
'hobby':hobby,
'info':info,
'a':a,
}
# 模板渲染--字符串替换--替换完成之后,才能html文件数据发送给浏览器客户端
return render(request,'home.html',data)
# 向home文件中传递字典类型数据
home.html:
{{变量}}和
{% 逻辑 %} 接收数据
万能的据点号(逗号)
<body>
<p>{{ name }}</p>
<p>{{ age }}</p>
<p>{{ hobby.0 }}</p> #取出列表索引为0的数据
<p>{{ info.username }}</p> #取出字典的对应值
<p>{{ a }}</p>
<p>{{ a.xx }}</p>
<p>{{ a.show_phone }}</p> #取出类中函数
<!-- 调用方法不能加括号,意味着不能使用有参数的函数或者方法 -->
</body>
2.过滤器
在数据变量的基础上完成进一步加工
在Django的模板语言中,通过使用 过滤器 来改变变量的显示。
过滤器的语法: {{ value|filter_name:参数 }}
使用管道符"|"来应用过滤器,可以链式调用
1.length :返回值的长度,作用于字符串和列表。
{{ value|length }}
2.default :如果一个变量是false或者为空,使用给定的默认值。 否则,使用变量的值
{{ value|default:"nothing"}} 如果value没有传值或者值为空的话就显示nothing
3.filesizeformat:
将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB',)
{{ value|filesizeformat }}
4.slice :可切片的数据类型
{{value|slice:"0:2"}} #左包右不包
4.date :时间格式化,如果 value=datetime.datetime.now()
{{ value|date:"Y-m-d H:i:s"}} #年-月-日 时:分:秒 2021-03-09 16:28:19
5.safe :
Django的模板中在进行模板渲染的时候会对HTML标签和JS等语法标签进行自动转义, 为了防止xss攻击(跨站脚本攻击), 为了在Django中关闭HTML的自动转义
例如:value = "<a href='#'>百度</a>"
{{ value|safe}}
6.truncatechars :内容过多,不好显示,截断字符,后面的用省略号代替(...)
例如:value = 'hello my world hello my girl'
{{ value|truncatechars:6}} # 结果:hel... 三个点也在截断的参数里
7.truncatewords :内容过多,不好显示,截断多少单词(单词以空格区分),后面的用省略号代替(...)
例如:value = 'hello my world hello my girl'
{{ value|truncatechars:3}} # 结果:hello my world...
8.cut :移除value中所有的与给出的变量相同的字符串
例如:value = 'hello my world'
{{ value|cut:' ' }} #hellomyworld 移除空格
9.join : 使列表中的数据连接成字符串
{{ list|join:',' }}
3.标签Tags :
1.for标签 :
循环列表
<ul>
{% for i in hobby %}
{# {% for i in hobby reversed %} 倒序循环 #}
<li>{{ i }}</li>
{% endfor %}
</ul>
循环字典
<ul>
{% for k,v in info.items %} <!--循环键和值,还可以用keys和values-->
<li>{{ k }}--{{ v }}</li>
{% endfor %}
</ul>
注:循环序号可以通过{{forloop}}本次循环对象来显示,必须在循环内部用 ,forloop是循环器,通过点来使用功能
forloop.counter 当前循环的索引值(从1开始),
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等
forloop.parentloop :例如 hobby = [[1,2,3],[11,22,33]]
<ul>
{% for i in hobby %}
{% for j in i %}
<li>{{ j }}--{{ forloop.parentloop.counter }}</li>
{% endfor %}
{% endfor %}
</ul>
for ... empty :给出的数据是空的或者没有被找到时,可以有所操作。
{% for person in person_list %}
<p>{{ person.name }}</p>
{% empty %}
<p>没有数据</p>
{% endfor %}
2.if标签
if语句支持 : and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断,注意条件两边都有空格。
{% if age > 18 %} <!-- 比较符号两边必须有空格, 可以结合过滤一起使用 -->
<h2>太大了</h2>
{% elif age < 18 %}
<h2>太嫩了</h2>
{% else %}
<h2>鸿昌</h2>
{% endif %}
也可以结合过滤器使用
{% if user_list|length > 5 %} <!--结合过滤器来使用-->
七座豪华SUV
{% else %}
黄包车
{% endif %}
3.with :给一个复杂的变量起别名
注意: 等号左右不要加空格
{% with total=business.employees.count %}
{{ total }} <!--只能在with语句体内用-->
{% endwith %}
或 with...as...
{% with business.employees.count as total %}
{{ total }}
{% endwith %}
4.模板继承 :
{% block css %}..预留钩子.. {% endblock %} -- (css是名字可随意写),
{% extends 'index.html' %}继承主文件
例如:点击不同的菜单栏,只更改主页内容,菜单栏和导航栏不会变化
urls.py
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
url(r'^menu1/', views.menu1),
url(r'^menu2/', views.menu2),
url(r'^menu3/', views.menu3),
]
views.py
from django.shortcuts import render
def index(request):
return render(request,'index.html')
def menu1(request):
return render(request,'menu1.html')
def menu2(request):
return render(request,'menu2.html')
def menu3(request):
return render(request,'menu3.html')
templates目录下html文件:
index.html ,主文件至少预留三个block代码块:css,页面内容,js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.clearfix{
content: '';
display: block;
clear: both;
}
.left-menu{
float: left;
200px;
text-align: center;
background-color:palegreen;
}
.content{
800px;
float: left;
}
</style>
{% block css %} <!--预留css代码块-->
<style>
.header{
background-color: yellow;
color: aqua;
height: 60px;
}
</style>
{% endblock %}
</head>
<body>
<div>
<div class="header">
顶部导航菜单
<button>个人中心</button>
</div>
<div class="main clearfix"> <!--菜单栏-->
<div class="left-menu">
<p>
<a href="/menu1/">菜单1</a>
</p>
<p>
<a href="/menu2/">菜单2</a>
</p>
<p>
<a href="/menu3/">菜单3</a>
</p>
</div>
<div class="content">
{% block content %} <!--预留页面内容代码块-->
index内容部分
{% endblock %}
</div>
</div>
</div>
</body>
{% block js %} <!--预留js代码块-->
{% endblock %}
</html>
menu1.html 菜单1页面,继承主文件
{% extends 'index.html' %} <!--继承母模板-->
{% block css %} <!--修改css样式-->
<style>
.header{
background-color: pink;
color: aqua;
height: 60px;
}
</style>
{% endblock %}
{% block content %} <!--修改页面内容-->
{{ block.super }} <!--保留母模板的数据-->
菜单1部分
{% endblock %}
menu2.html
{% extends 'index.html' %}
{% block content %}
菜单2部分
{% endblock %}
menu3.html
{% extends 'index.html' %}
{% block content %}
菜单3部分
{% endblock %}
5.组件
可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方,文件的任意位置按如下语法导入即可。
{% include 'nav.html' %} <!--引入nav文件-->
例如:有个如下的导航栏,nav.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c2{
background-color: aqua;
height: 60px;
}
</style>
</head>
<body>
<div class="c2">
<span>顶部导航栏</span>
</div>
</body>
</html>
嵌入导航栏的页面,xx.html
<body>
{% include 'nav.html' %} <!--引入nav文件-->
<div>
<h1>xx页面</h1>
</div>
</body>
6.自定义标签和过滤器
流程
1 创建应用
2 在应用中创建一个templatetags的文件,名称必须叫templatetags
3 在templatetags文件夹中创建一个py文件,名称随意mytages
4 文件中写如下内容
from django import template
# 注册器变量名称必须叫做register
register = template.Library()
#1.自定义过滤器: 1 写函数 2 通过filter装饰器装饰函数
#过滤器最多两个参数
@register.filter
def addxx(v1): #一个参数,这个参数是{{ name|addxx }}的name数据
s = v1 + 'xx'
return s
@register.filter
def addxx2(v1,v2): #两个参数,这个参数是{{ name|addxx:'oo' }}的name和oo数据
s = v1 + 'xx' +v2
return s
#2.自定义标签
@register.simple_tag
def xxtag(v1,v2,v3): #自定义标签,参数可以是任意个数
return '+'.join([v1,v2,v3])
使用 home.html
{% load mytages %} <!--必须先加载,重启项目,才能使用自定义标签和过滤器-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--使用过滤器-->
<p>{{ name|addxx }}</p>
<p>{{ name|addxx2:'oo' }}</p>
<!--使用标签-->
<p>{% xxtag 'aa' 'bb' 'cc' %}</p>
</body>
</html>
inclusion_tag 自定义标签:主要用来做动态组件
1 创建应用
2 在应用中创建一个templatetags的文件,名称必须叫templatetags
3 在templatetags文件夹中创建一个py文件,名称随意mytages
4 文件中写如下内容
from django import template
# 注册器变量名称必须叫做register
register = template.Library()
@register.inclusion_tag('nav.html') #参数就是那个组件html文件
def custom_nav(v1): #参数可以是任意个数
print(v1) #打印的是接收的的hobby数据['与姑娘', '李姑娘', '加固年']
return {'nav_data':v1} #nav.html里用什么数据就返回什么数据,必须是字典
导航栏: nav.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c2{
background-color: aqua;
height: 60px;
}
.c1{
color: blue;
}
</style>
</head>
<body>
<div class="c2">
{% for item in nav_data %}
<span class="c1">{{ item }}</span>
{% endfor %}
</div>
</body>
</html>
home.html
在某个html文件中使用这个动态组件
{% load mytages %}
{% custom_nav hobby %}
{% load mytages %} <!--必须先加载,才能使用自定义标签和过滤器-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% custom_nav hobby %} <!--使用标签,把hobby数据传到自定义标签函数中-->
</body>
</html>
views.py
from django.shortcuts import render
def home(request):
hobby = ['王姑娘2', '于姑娘2', '何姑娘3']
data = {
'hobby':hobby,
}
# 模板渲染--字符串替换--替换完成之后,才能html文件数据发送给浏览器客户端
return render(request, 'home.html', data)
7.静态文件引入设置
1 在项目根目录下创建一个文件夹,名称随意,比如叫做jingtaiwenjianjia
2 将所需静态文件放到这个文件夹中,例如:bootstrap 文件
3 在settings.py文件中做如下配置
STATIC_URL = '/static/' #静态文件夹路径别名,
STATICFILES_DIRS = [ #导入静态文件路径方向
os.path.join(BASE_DIR, 'jingtaiwenjianjia'),
]
4 在html文件中就可以通过static别名来进行静态文件的引入了
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 方式1 -->
{# <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">#}
<!-- 方式2,别忘了先load static -->
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
</head>
<body>
<h1>这是kk页面</h1>
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>姓名</th>
<th>爱好</th>
</tr>
</thead>
<tbody>
<tr>
<td>老王</td>
<td>隔壁</td>
</tr>
<tr>
<td>老白</td>
<td>鸡哥</td>
</tr>
<tr>
<td>鸡哥</td>
<td>老王</td>
</tr>
</tbody>
</table>
</body>
</html>