模板层
模板语法传值
{{ }}:传变量相关的值,如:整型、列表、字典、函数等等
{% %}:传逻辑相关的值,如:for循环、if判断、static动态解析等等
传递基本数据类型
整型、浮点型、字符串、布尔值、列表、字典、元组、集合,所有的Python数据类型都可以传
基本数据类型的取值
# Django模板语法的取值,是固定的格式,只能采用"句点符":"."
# 既可以点字典的建,可以点列表、元组等等的索引
<p>{{ l.2 }}</p>
<p>{{ d.name }}</p>
# 还可以两者混用
<p>{{ d.hobby.2.info }}</p>
def index(request):
i = 111
f = 1.1
s = '你好'
b = True
l = [111, 'hello', [111]]
d = {'name': 'liu', 'age': 12, 'hobby': [11, 22, {'info': 'NB'}]}
t = (111, 222,)
se = {111, 222}
return render(request, 'index.html', locals())
传递函数
# 传递函数名会自动加括号调用,但是模板语法不支持给函数传递额外的参数
"""后端"""
def index(request):
def func():
print('我执行了')
return '我是函数'
return render(request, 'index.html', locals())
"""前端"""
<p>{{ func }}</p>
传递类和对象及对象内的方法
# 传递类名的时候也会加括号调用(实例化),也不支持传递参数
# 传递对象的时候可以点对象的方法,返回对应方法的返回值
"""后端"""
def index(request):
class MyClass(object):
def get_self(self):
return 'self'
@staticmethod
def get_func():
return 'func'
@classmethod
def get_class(cls):
return 'class'
# def __str__(self):
# return '类中的__str__方法'
obj = MyClass()
return render(request, 'index.html', locals())
"""前端"""
<p>{{ MyClass }}</p> # <app01.views.index.<locals>.MyClass object at 0x0000000003EE90D0>
<p>{{ obj }}</p> # <app01.views.index.<locals>.MyClass object at 0x0000000003ECC100>
<p>{{ obj.get_self }}</p> # self
<p>{{ obj.get_func }}</p> # func
<p>{{ obj.get_class }}</p> # class
过滤器(过滤器最多接收两个参数)
# 过滤器类似于是模板语法内置的 内置方法
# Django内置有60多个过滤器,暂时了解10个左右
# 基本语法
{{ 数据|过滤器:参数 }}
safe:转义(可以识别字符串中的html代码)
"""模板语法默认是不识别字符串中的html代码的"""
# 第一种:前端过滤器转义
# 后端数据
hhh = '<h1>liu</h1>'
# 前端过滤器
<p>{{ hhh|safe }}</p>
# 第二种:后端转义
from django.utils.safestring import mark_safe
res = mark_safe('<h1>liujie</h1>')
<p>{{ res }}</p>
"""
有了这个过滤器后,在写全栈项目的时候,前端代码不一定要写在前端页面,也可以在后端先写好,然后传递给前端页面
"""
length:统计字符长度
# 后端数据
s = '你好'
# 前端过滤器
<p>{{ s|length }}</p> # 2
default:默认值(第一个参数布尔值为True就展示第一个参数,反之则为后面的值)
# 后端数据
b = True
# 前端过滤器
<p>{{ b|default:'False' }}</p> # True
filesizeformat:计算文件大小
# 后端数据
i = 111546165498
# 前端过滤器
<p>{{ i|filesizeformat }}</p> # 103.9 GB
date:格式化时间(把人类难以看清楚的时间改为人类易读的时间)
# 后端数据
import datetime
time = datetime.datetime.now()
# 前端过滤器
<p>{{ time|date:'Y-m-d H:i:s' }}</p> # 2023-01-14 17:25:59
slice:切片操作,支持步长
# 后端数据
s = 'daasdasd'
# 前端过滤器
<p>{{ s|slice:'0:4:2' }}</p> # da
truncatechars:切取字符(包含三个点)
# 后端数据
info = '多发的发放阿萨德发顺丰阿斯顿发份'
# 前端过滤器
<p>{{ info|truncatechars:9 }}</p> # 多发的发放阿...
truncatewords:切取单词(按照空格切,不包含三个点)
# 后端数据
info = '多 发 的 发放 阿萨 德发顺丰 阿斯顿发份'
# 前端过滤器
<p>{{ info|truncatewords:5 }}</p> # 多 发 的 发放 阿萨 ...
cut:移除指定的字符
# 后端数据
info = '多 发 的 发放 阿萨 德发顺丰 阿斯顿发份'
# 前端过滤器
<p>{{ info|cut:' ' }}</p> # 多发的发放阿萨德发顺丰阿斯顿发份
join:按照指定的字符进行拼接
# 后端数据
l = [111, 'hello', [111]]
# 前端过滤器
<p>{{ l|join:'-' }}</p> # 111-hello-[111]
add:拼接(字符与字符拼接,数字与数字做加法运算)
"""
字符与字符是做拼接,数字与数字是做加法
字符与数字不能拼接
"""
# 后端数据
i = 111
s = 'daasdasdfsfsfsdfsd'
info = '多 发 的 发放 阿萨 德发顺丰 阿斯顿发份'
# 前端过滤器
<p>{{ i|add:10 }}</p> # 121
<p>{{ s|add:info }}</p> # daasdasdfsfsfsdfsd多 发 的 发放 阿萨 德发顺丰 阿斯顿发份
标签
for循环
语法
{% for 属性名 in 可迭代对象 %}
<p>{{ }}</p>
{% endfor %}
内置属性:forloop
{% for foo in l %}
<p>{{ forloop }}</p>
{% endfor %}
# 浏览器展示的
{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 3, 'revcounter0': 2, 'first': True, 'last': False}
"""forloop属性key的介绍"""
# counter0:表示当前元素的索引
# counter:表示当前元素所在容器的位数
# first:当前元素是容器中的第一个元素时value为True,其他情况value皆为False
# last:当前元素时容器中最后一个元素时value为False,其他情况value皆为True
empty:可迭代对象为空的时候总empty下面的代码
{% for lll in l %}
<p>{{ lll }}</p>
{% empty %}
<p>可迭代对象里面没有元素,没法for循环的时候自动走empty</p>
{% endfor %}
循环列表
"""循环列表"""
# 后端数据
l = [111, 'hello', [111], 'liu', 'song']
# 前端
{% for lll in l %}
<p>{{ lll }}</p>
{% endfor %}
循环字典
"""循环字典"""
# 后端数据
d = {'name': 'liu', 'age': 12, 'hobby': [11, 22, {'info': 'NB'}]}
# 前端
# 循环字典的key
{% for ddd in d.keys %}
<p>{{ ddd }}</p>
{% endfor %}
# 循环字典的值
{% for ddd in d.values %}
<p>{{ ddd }}</p>
{% endfor %}
# 字典的key和value组成一个元组 ('name', 'liu')
{% for ddd in d.items %}
<p>{{ ddd }}</p>
{% endfor %}
if判断
{% if b %}
<p>b的布尔值是True,展示该标签</p>
{% elif s %}
<p>b的布尔值是False,s的布尔值是True,展示该标签</p>
{% else %}
<p>b和s的布尔值都是False,展示该标签</p>
{% endif %}
for循环和if判断混用
# 后端数据
l = [111, 'hello', [111], 'liu', 'song']
# 前端代码
{% for foo in l %}
{% if forloop.first %}
<p>这是第一行数据</p>
{% elif forloop.last %}
<p>这是最后一行数据</p>
{% else %}
<p>{{ foo }}</p>
{% endif %}
{% endfor %}
# 浏览器渲染出来的页面
这是第一行数据
hello
[111]
liu
这是最后一行数据
with:给数据起别名(变量名)
当一个数据要用"句点符"点多次时,可以给这个数据起一个别名,方便多次使用,就类似后端中的变量名
语法
{% with 数据 as 给数据起的别名 %}
<p>在with内,用数据的别名可以直接访问到后端的数据,类似变量名</p>
{% endwith %}
实例
"""
下面的例子中"NB"这个数据被嵌套了很多层,当我们要重复使用这个数据时就可以用with给他起一个别名
"""
# 后端数据
d = {'name': 'liu', 'age': 12, 'hobby': [11, 22, {'info': 'NB'}]}
# 前端代码
{% with d.hobby.2.info as nb %}
<p>{{ nb }}</p>
{% endwith %}
自定义过滤器、标签、inclusion_tag
要自定义过滤器、标签等要先做以下准备
"""
1、在应用下创建一个名字必须叫templatetags文件夹
2、在该文件夹内创建任意名称的py文件,例如:mytag.py
3、在刚刚创建的py文件内必须写下面两行代码
from django import template
register = template.Library()
4、在创建的py文件下写过滤器、标签、inclusion_tag
"""
自定义过滤器
语法
# 自定义过滤器
@register.filter(name='过滤器名字')
def 函数名(最多接收两个参数):
return res
# 前端使用
{% load 创建的py文件 %}
<p>{{ 数据|自定义过滤器的名字:参数 }}</p>
实例
# 自定义过滤器
@register.filter(name='number_of_words')
# 统计小说字数的过滤器
def number_of_words(i):
# 判断字符串内是否为整型
if not i.isdigit():
return ''
# 把字符型转为整型
i = int(i)
# 判断字数是否大于一万
if i < 10000:
return i
# i大于一万时除以一万并保留两位小数
i = round(i / 10000, 2)
# i转为字符型并加上单位万
res = str(i) + '万'
return res
# 前端
{% load mytag %}
<p>该图书共 {{ ii|number_of_words }} 字</p>
自定义标签
语法
# 自定义标签
@register.simple_tag(name='标签名')
def 函数名(可以接收多个参数):
return res
# 前端使用
{% load 创建的py文件 %}
<p>{% 标签名 参数(每个参数之间要空一格) %}</p>
实例
# 自定义标签
@register.simple_tag(name='plus')
def plus(name, age, weight, height):
return f'我叫{name},今年{age}岁,身高{weight}cm,体重{height}kg'
# 前端
{% load mytag %}
<p>{% plus 'dick' 18 180 70 %}</p>
自定义inclusion_tag
"""
内部原理
先定义一个方法
在页面调用该方法,并且可以传值
该方法会生成一些数据然后传递给一个html页面
之后将渲染好的结果放到调用的位置
"""
语法
"""
括号内的html文件一般都不是完整的,没有html、body标签,只有需要传递给前端的标签
"""
# 自定义inclusion_tag
@register.inclusion_tag('html文件')
def 函数名(参数):
data = []
# 第一种传值方式
# return {'data': data} # 传值给上面括号内的html文件
# 第二种传值方式
return locals() # 传值给上面括号内的html文件
# 使用
{% 函数名 '参数' %}
实例
# 自定义inclusion_tag
@register.inclusion_tag('show_list.html')
def show_list(n):
# 列表生成式
data = [f'第{i}项' for i in range(n)]
# 第一种传值方式
# return {'data': data}
# 第二种传值方式
return locals()
# 前端
{% show_list 10 %}
# show_list.html页面
# 整个html文件只写了这个标签
<ul>
{% for i in data %}
<li>{{ i }}</li>
{% endfor %}
</ul>
# 展示到浏览器的
第0项
第1项
第2项
第3项
第4项
第5项
第6项
第7项
第8项
第9项
inclusion_tag总结
当html页面某一个地方的页面需要传参才能动态的渲染出来,并且多个页面上都需要使用到该局部时,那么就可以考虑将该局部页面做成inclusion_tag的形式
模板的继承
有的网站整体都差不多,只是某一些局部在做变化,这就是用到了模板的继承
语法
1、继承一个html页面
# 新建一个html文件,清空所有的内容,在里面写
{% extends '要继承的html页面' %}
2、划定主页面(被继承的html页面)中可以被修改的区域
# 子页面继承了主页面后,跟主页面是一模一样的,需要在主页面上提前划定可以被修改的区域
{% block '起一个模板名' %}
模板内容
{% endblock %}
3、子页面修改划定区域的内容
# 子页面先声明要修改那一块区域,然后再修改
{% block '模板名' %}
子页面内容
{% endblock %}
4、子页面继续使用主页面的内容
# 子页面除了可以自己写自己的内容以外,还可以继续使用主页面的内容
{% block '模板名' %}
{{ block.super }}
子页面内容
{% endblock %}
"""
一般情况下模板页面至少应该有三块可以被修改的区域
1、css区域
2、html区域
3、js区域
"""
{% block css %}
css代码
{% endblock %}
{% block content %}
html局部的代码
{% endblock %}
{% block js %}
js代码
{% endblock %}
"""
一般情况下,模板页面上划定的区域越多,那么该模板的扩展性就越高,但是如果太多那还不如重新写一个页面
"""
实例
// 模板页面(主页面)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--引入jQuery的js文件t-->
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<!--引入bootstrap的js文件-->
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<!--引入bootstrap的css文件-->
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<title>Title</title>
{% block css %}
<style>
h1 {
color: red;
}
</style>
{% endblock %}
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
<form class="navbar-form navbar-left">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<div class="container">
<div class="row">
<div class="col-md-3">
<ul class="nav nav-pills nav-stacked">
<li role="presentation" class="active"><a href="/home/">主页面</a></li>
<li role="presentation"><a href="/login/">登录</a></li>
<li role="presentation"><a href="/reg/">注册</a></li>
</ul>
</div>
<div class="col-md-9">
{% block home %}
<h1 class="text-center">首页</h1>
<div class="jumbotron">
<h1>Hello, world!</h1>
<p>...</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more</a></p>
</div>
{% endblock %}
</div>
</div>
</div>
{% block js %}
<script>
alert('首页')
</script>
{% endblock %}
</body>
</html>
// 子页面一
{% extends 'home.html' %}
{% block home %}
<h1 class="text-center">登录</h1>
<form action="">
<p>账号:<input type="text" class="form-control"></p>
<p>密码:<input type="password" class="form-control"></p>
<p><input type="submit" value="登录" class="form-control btn btn-success"></p>
</form>
{% endblock %}
{% block css %}
<style>
h1 {
color: green;
}
</style>
{% endblock %}
{% block js %}
<script>
alert('登录页面')
</script>
{% endblock %}
// 子页面二
{% extends 'home.html' %}
{% block home %}
<h1 class="text-center">注册</h1>
<form action="">
<p>账号:<input type="text" class="form-control"></p>
<p>密码:<input type="password" class="form-control"></p>
<p><input type="submit" value="注册" class="form-control btn btn-danger"></p>
</form>
{% endblock %}
{% block css %}
<style>
h1 {
color: yellow;
}
</style>
{% endblock %}
{% block js %}
<script>
alert('注册页面')
</script>
{% endblock %}
模板的导入
"""
将页面的某一个局部当成模块的形式
那个地方需要就可以直接导入使用
"""
{% include 要导入的局部 %}
{% include 'login.html' %}
标签:return,前端,html,第五章,过滤器,模板,页面
From: https://www.cnblogs.com/liuhousheng/p/17058778.html