Django模板层学习笔记
一. 前言
Django模板层的知识包括标签、过滤器、自定义标签、自定义过滤器以及inclusion_tag,最重要的是模板的继承和导入。
首先模板层最重要的是模板语法,之前我们提过涉及到变量用模板语法{{ }},涉及到逻辑用模板语法{% %},这里再追加几点。过滤器在模板语法{{ }}中写,而且只能传两个参数;标签在模板语法{%%}中写,而且能传多个参数(参数间用空格隔开)。模板的继承与导入也是在模板语法{%%}中写。
接下来再回顾一下后端朝前端页面传递数据的两种方式:
# 第一种
return render(request, 'index.html', {'nums': nums}) # 第二种
return render(request, 'index.html', locals())
该两种方法有利有弊,不过我们偏爱locals()。
后端除了能向前端提交python的基本数据类型:int、float、str、list、dict、tuple、set数据外,还能提交函数与类的对象。当我们传递函数名给前端时,会自动调用该函数拿到函数return的结果,但是不支持传参,所以只能传递无参函数名。当传递类的对象obj给前端时,相当于print(obj),前端拿到的是该obj的内存地址,因为print(obj)走的是类的__str__()方法。所以传递类的对象时,我们可以重写__str__()让前端拿到想要的内容。
前端想要获取后端传递过来的容器类型中的元素时,统一使用句点符(.):
<!--假设前端拿到的数据是 L = [1, 2, 3] D = {'age': 18}-->
{{ L }} <!--[1, 2, 3]-->
{{ L.1 }} <!-- 2 索引也是从0开始--> {{ D }} <!--{'age': 18}-->
{{ L.age }} <!-- 18 -->
前端可以调用python自带的内置方法,不过只能调用不需要传参的,比如字典dic的dic.keys(),dic.values(),dic.items()等,注意:在前端调用方法不需要加(),直接dic.keys即可。
模板语法的注释不会展示到前端(用谷歌浏览器的检查也看不到),只能在后端看到,原生的HTML注释前后端都可以看到。
二. 过滤器
过滤器在模板语法{{ }}中书写,实际上过滤器内部走的是后端的语法,过滤器最多支持传两个参数(会把|左边的参数当做过滤器的第一个参数传进去),不过可以把参数改成容器类型,然后在内部动手脚处理参数中的数据,间接实现传递多参数,这需要我们自定义过滤器来实现。
过滤器基本语法:{{ 参数1|过滤器名字:参数2 }} 有些过滤器没有参数2。
- 统计字符串长度 {{ s|length }}:会将s当做length的参数传进去,内部就是后端语法
- 获取的数据为空就返回default后面定义的值{{ s|default:'s是空的字符串' }}
- 将数字转化为成表示文件大小的格式{{ file_size|filesizeformat }}
如果file_size是204800,执行该过滤器后是 200.0KB
- 格式化时间{{ ctime|date:'Y-m-d' }}
不需要同后端一样加%('%Y-%m-%d'),如果ctime是2019-06-11 16:56:38.903314,执行完该过滤器后是2019-06-11。
- 字符串的切片操作{{ s|slice:'0:8:2' }}
如果s='hello world',执行完该过滤器后是‘hlow’,slice后面的参数同python字符串切片参数一样,开头:结尾:步长,其中步长默认为1,切片顾头不顾尾。
- 截取固定长度的字符串{{ s|truncatechars:10 }}
如果s='hello world',执行完该过滤器后是‘hello w...’,超出长度的部分会用...代替,当我们参数为10时,实际上截取的字符串长度为7,因为...占3位。
- 按照空格截取文本内容{{ s|truncatewords:2 }}
如果s='he llo wor ld',执行完该过滤器后是:‘he llo ...’,截取至前两个空格,之后的内容用...表示。
- 加法亦或是字符串拼接{{ n1|add:n2 }}
如果n1=2, n2=4,那么结果为6。如果n1='hello', n2='world',那么结果为'helloworld'。
重点:
当我们后端向前端提交的字符串含有标签时,比如'<h1>this is title</h1>',为了防止脚本攻击(比如<script>while(1){alert('come on')}</script>),前端之后把你当成普通的字符串。当我们想要让前端帮我们执行提交的字符串中的标签内容时,有两种方式。
- 在前端通过{{ 字符串|safe }}告诉前端字符串很安全,让它大胆执行。
- 后端用模块操作一下字符串,告诉前端我们给它的字符串很安全。
from django.utils.safestring import mark_safe def index(request):
html = reverse('index')
s = '<h1>this is title</h1>'
s = mark_safe(s)
return render(request, 'index.html', locals()) # 前端直接{{ s }}即可
二. 标签
标签在模板语法{%%}中书写,{%%}涉及到逻辑,标签一般是for循环,if判断以及它们的嵌套使用,除此之外还有empty标签。
for循环中可以使用forloop来给我们提供一些信息:
1. for循环
<!--l = [1, 2, 3, 4, 5]-->
{% for foo in l %}
<p>{{ foo }}</p>
<p>{{ forloop }}</p>
{% endfor %}
2. if判断
{% if flag %}
<p>flag不为空</p>
{% else %}
<p>flag是空</p>
{% endif %}
3. if与for嵌套使用
{% for foo in s %}
{% if forloop.first %}
<p>这是第一次</p>
{% elif forloop.last %}
<p>这是最后一次</p>
{% else %}
<p>keep up</p>
{% endif %}
{% endfor %}
4. empty
{% for foo in l %}
{% if forloop.first %}
<p>这是我的第一次</p>
{% elif forloop.last %}
<p>这是最后一次了啊</p>
{% else %}
<p>嗨起来!!!</p>
{% endif %}
{% empty %}
<p>你给我的容器类型是个空啊,没法for循环</p>
{% endfor %}
5. 补充
当后端传来的数据中,我们想要的数据需要句点符点很多次才能拿到且后面还需要用到该数据时,我们可以选择给该数据取别名。
三.自定义过滤器与标签、inclusion_tag
要自定义过滤器与标签,必须先做三件事:
- 在应用文件夹下新建templatetags文件夹(必须叫这个名字)
- 在templatetags文件夹中新建一个py文件,名字任意,不过最好不要有中文
- 在该py文件中固定写以下两句代码:
from django import template register = template.Library()
再次强调,一定要按照以上步骤进行,文件夹一定要叫templatetags!!!
1. 自定义过滤器
from django import template register = template.Library() # 自定义过滤器
@register.filter(name='my_add') # name是HTML页面中调用该过滤器用的名字
def my_add(a, b):
return a+b
2. 自定义标签
from django import template register = template.Library() @register.simple_tag(name='my_tag')
def my_tag(a, b, c):
return a + b + c
3.自定义inclusion_tag
from django import template register = template.Library() @register.inclusion_tag('login.html', name='login')
def login(n):
l = ['第%s项' % i for i in range(n)]
return {'l': l}
<!--login.html-->
<ur>
{% for foo in l %}
<li>{{ foo }}</li>
{% endfor %}
</ur>
在该例子中,我们在前端调用inclusion_tag时:
{% load my_tags %}
{% login 5 %}
首先会将参数5传给login函数,函数执行完后的结果提交至login.html,然后将login.html的页面显示在调用该inclusion_tag的地方。
inclusion_tag会将渲染过的login.html界面返回至调用它的位置,正是因为这种机制,所以它所渲染那个html页面中可以不需要head和body等各种标签,你需要返回什么就在里面写什么。
4.结论
想要使用自定义的过滤器、标签和inclusion_tag,必须要先在html界面中加载该模块
<!--加载my_tags.py模块-->
{% load my_tags %} {{ n1|my_add:n2 }} <!--调用自定义过滤器-->
{% my_tag n1 n2 n3 %} <!--调用自定义标签-->
{% login 5 %} <!--调用自定义inclusion_tag-->
四. 模板的继承与导入
1. 模板的继承
1.1 首先需要被继承的模板中划分多个区域:
{% block 给区域起的名字 %} {% endblock %}
1.2 通常情况下一个模板中至少有三块区域:
{% block css %}
页面css代码块
{% endblock %} {% block js %}
页面js代码块
{% endblock %} {% block content %}
页面主体内容
{% endblock %}
1.3 子模板继承模板,首先要先继承模板所有的内容:
{% extends 'home.html' %}
1.4 根据被block快的名字修改指定区域的内容
{% block content %}
<h1>登录页面</h1>
<form action="">
<p>username:<input type="text" class="form-control"></p>
<p>password:<input type="text" class="form-control"></p>
<input type="submit" class="btn btn-success">
</form>
{% endblock %}
1.5 可以使用{{ block.super }}使用父模板的该block的内容(使用该方法是没有提示,要手打)
{% block content %}
{{ block.super }}
{% endblock %}
注意:原模板中的block区域越多越好,因为越多代表可以修改的细节很多,扩展性就越强。继承后,子模板只能修改block区域中的内容。
2. 模板的导入
模板导入同自定义标签inclusion_tag有点像,都是将一个HTML页面显示到调用它们的地方,而且他们的HTML页面都是要啥就写啥就行了,不需要body、head等标签。不过inclusion_tag是动态的,可以传递参数,而模板导入是静态的。
模块导入{% include '想导入的html文件名' %}:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login2</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<!--导入模板index2.html-->
{% include 'index2.html' %}
</body>
</html>
<h1>我是这条gai最靓的仔</h1>
<form action="">
<p><input type="text"></p>
<p><input type="text"></p>
<input type="submit">
</form>
index2.html
3. 静态文件配置
当我们为了让路由名字改变时我们不需要修改HTML页面和视图函数中的内容,我们引入了反向解析。同理,为了防止settins.py文件夹中static文件夹的接口前缀改变而我们不需要html页面中head中script和link的接口前缀(需要修改的前提是他们导入的是static文件夹中的东西),我们引入了静态文件配置。
{% load static %} <link rel='stylesheet' href="{% static 'css/mycss.css'%}"> # 第一种方式
<link rel='stylesheet' href="{% get_static_prefix %}css/mycss.css"> # 第二种方式
Django模板层学习笔记的更多相关文章
- NVelocity模板引擎学习笔记
NVelocity模板引擎学习笔记 学习模板引擎有一段时间现在做一些总结
- Django RF:学习笔记(8)——快速开始
Django RF:学习笔记(8)——快速开始 安装配置 1.使用Pip安装Django REST Framework: pip install djangorestframework 2.在Sett ...
- 完整的Django入门指南学习笔记2
part2: 前沿 在第一节中,我们安装了项目所需要的一切:Python3.6以及在虚拟环境中运行的Django2.0,这部分教程继续在项目上编写代码. 开始写代码前,先讨论下项目的相关背景知识,然后 ...
- django——模板层
每一个Web框架都需要一种很便利的方法用于动态生成HTML页面. 最常见的做法是使用模板. 模板包含所需HTML页面的静态部分,以及一些特殊的模版语法,用于将动态内容插入静态部分. 说白了,模板层就是 ...
- 完整的Django入门指南学习笔记3
前言 在本节课中,我们将深入理解两个基本概念: URLs 和 Forms.在这个过程中,我们还将学习其它很多概念,如创建可重用模板和安装第三方库.同时我们还将编写大量单元测试. 如果你是从这个系列教程 ...
- Django模板层
一:模板简介 二:模板语法值变量 三: 模板之过滤器 四: 模板之标签 五:自定义标签和过滤器 一:模板简介 def current_datetime(request): now=datetime ...
- 关于Django路由层简单笔记
Django—路由层 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来的某个U ...
- Django——模板层(template)(模板语法、自定义模板过滤器及标签、模板继承)
前言:当我们想在页面上给客户端返回一个当前时间,一些初学者可能会很自然的想到用占位符,字符串拼接来达到我们想要的效果,但是这样做会有一个问题,HTML被直接硬编码在 Python代码之中. 1 2 3 ...
- Django模板层之templates
一 模版简介 你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. def current_datetime(request): now ...
随机推荐
- linux增加history时间戳
增加环境变量到/etc/profile export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S " export HISTSIZE=9999
- 当学术邂逅浪漫 – 记MobiCom 2015大会
作者:微软亚洲研究院主管研究员 刘云新 今年的MobiCom大会在著名的浪漫之都巴黎举行.通常于欧洲举办的会议的参会人数会相对少一些,但今年的MobiCom大会吸引了近400人参加,绝不少于往年.浪漫 ...
- Hexo next主题安装algolia
一直在使用hexo写自己的博客,最近博客刚刚搬家重新搞了下博客: 1.为hexo添加站内搜索 我用的是algolia,在next主题5.x以上的版本集成了algolia站内搜索功能,我们只需要简单的配 ...
- 关于struct stat
需要使用struct stat 类型时如果编译不过,修改Makefile: ##CFG_INC := -I$(MPI_DIR)/api/so/##CFG_INC += -I$(BASE_DIR)/pu ...
- 再谈拍照,OPPO这次拿什么和iPhone7拼?
一年一度的iPhone新机如期而至,双摄像头成为iPhone 7 Plus标配,尽管在这之前,双摄像头已有少数厂商在手机上装备,但苹果一出,市场必定全面跟进.无论各大厂商是否采用双摄像头,在手机拍照 ...
- JMeter-WebService接口的测试
前言 JMeter3.2版本之后就没有SOAP/XML-RPC Request插件了,那么该如何进行webservice接口的测试呢? 今天我们来一起学习一下怎么在3.2以后版本的JMeter进行we ...
- 基础JavaScript练习(三)总结
任务目的 实践JavaScript数组.字符串相关操作 任务描述 基于任务四进行升级 将新元素输入框从input改为textarea 允许一次批量输入多个内容,格式可以为数字.中文.英文等,可以通过用 ...
- Yuchuan_Linux_C编程之二 GCC编译
一.整体大纲 二.gcc编译的四个阶段
- CSS3新单位vw,vh,vmin,vmax详解
1,vw,vh,vmin,vmax是由视窗Viewport大小来决定的,单位1,代表1%,是一种相对单位,只要是为响应式适配视窗的一种解决方案: vw:view width(视窗宽度)的百分比,1vw ...
- jenkins-构建job成功后自动打tag到git仓库
需求:最近开发同事提出了个要求,每当Jenkins执行上线部署完成后,对当前代码进行自动打TAG到git仓库中,且只有当部署成功后才进行打TAG,防止构建失败也进行打过多的垃圾tag,然后便于下次进行 ...