模板层
模板语法
模版语法重点:
变量:{{ 变量名 }}
1 深度查询 用句点符
2 过滤器
标签:{{% % }}
模板语法的注释
不会展示到前端页面:{#调用python自带的内置方法,可以调用不需要传参的一些内置方法#}
原生html的注释
会展示到前端:<!--我是原生的html注释-->
模板语法之变量
view.py文件中
from django.shortcuts import render # Create your views here. def index(request): n = 6969 s = '您好 我是 23 号技 师 很高兴 为您 服务,希望您 能满意!(不带换的' l = ['a','b','c','d','e','f','g'] d = {'name':'xxx','password':'222','hobby':['看书','写字','琴棋书画']} t = ('关某某','谢某某','陈某某','容嬷嬷') st = {'python','java','php','golang'} def func(): return '你调用了我?' class Demo(object): def __init__(self,name): self.name = name def func(self): return self.name @classmethod def index(cls): return 'cls' @staticmethod def bar(name,age): return 'bar' def __str__(self): return '大帅比' obj = Demo('jason') print(obj) # 第一种 # return render(request,'index.html',{'n':n}) # 第二种 return render(request,'index.html',locals()) # 将当前所在的名称空间中的名字全部传递给前端页面
index.html文件中
<p> n >>>:{{ n }}</p> <p> s >>>:{{ s }}</p> <p> l >>>:{{ l }}</p> <p> d >>>:{{ d }},{{ d.hobby }}</p> <p> t >>>:{{ t }},{{ t.1 }}</p> <p> st>>>:{{ st }}</p> <p>{{ func }}</p> <p>{{ obj }}</p> <p>{{ obj.name }}</p> <p>{{ obj.func }}</p> <p>{{ obj.index }}</p> <p>{{ obj.bar }}</p>
注:
- 后端传函数名到前端,会自动加括号调用,但是不支持传参
- 前端获取后端传过来的容器类型的内部元素 统一采用句点符(.)
- 后端传对象到前端,就相当于打印了这个对象
- 前端能够调用python后端数据类型的一些不需要传参的内置方法
后端朝前端页面传递数据的方式
# 第一种 return render(request,'index.html',{'n':n}) # 第二种 return render(request,'index.html',locals()) # 将当前所在的名称空间中的名字全部传递给前端页面
过滤器
语法:
{{obj|filter__name:param}} 变量名字|过滤器名称:变量
-
default
如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:
{{ value|default:"nothing" }}
-
length
返回值的长度。它对字符串和列表都起作用。例如:
{{ value|length }}
如果 value 是 ['a', 'b', 'c', 'd'],那么输出是 4。
-
filesizeformat
将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB'
, '4.1 MB'
, '102 bytes'
, 等等)。例如:
{{ value|filesizeformat }}
如果 value
是 123456789,输出将会是 117.7 MB
。
-
date
如果 value=datetime.datetime.now()
{{ value|date:"Y-m-d H:i:s" }}
-
slice
如果 value="hello world"
{{ value|slice:"2:-1" }}
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
参数:要截断的字符数
例如:
{{ value|truncatechars:9 }}
-
safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:
value="<a href="">点击</a>"
{{ value|safe}}
- 前后端取消转义
前端:
|safe
后端:
from django.utils.safestring import mark_safe
xxx = mark_safe('<h1>我是h1标签</h1>')
标签
- for标签
遍历每一个元素:
<ul> {% for user in user_list %} <li>{{ user.name }}</li> {% endfor %} </ul>
可以利用{% for obj in list reversed %}反向完成循环。
遍历一个字典:
{% for key,val in dic.items %} <p>{{ key }}:{{ val }}</p> {% endfor %}
注:循环序号可以通过{{forloop}}显示
forloop.counter The current iteration of the loop (1-indexed) 当前循环的索引值(从1开始) forloop.counter0 The current iteration of the loop (0-indexed) 当前循环的索引值(从0开始) forloop.revcounter The number of iterations from the end of the loop (1-indexed) 当前循环的倒序索引值(从1开始) forloop.revcounter0 The number of iterations from the end of the loop (0-indexed) 当前循环的倒序索引值(从0开始) forloop.first True if this is the first time through the loop 当前循环是不是第一次循环(布尔值) forloop.last True if this is the last time through the loop 当前循环是不是最后一次循环(布尔值) forloop.parentloop 本层循环的外层循环
- for … empty
<ul> {% for user in user_list %} <li>{{ user.name }}</li> {% empty %} <li>空空如也</li> {% endfor %} </ul>
- if判断
if,elif和
else
{% if user_list %} 用户人数:{{ user_list|length }} {% elif black_list %} 黑名单数:{{ black_list|length }} {% else %} 没有用户 {% endif %}
if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。
-
with
定义一个中间变量,多用于给一个复杂的变量起别名。
注意等号左右不要加空格。
{% with total=business.employees.count %}
{{ total }} employee{{ total|pluralize }}
{% endwith %}
或
{% with business.employees.count as total %} {{ total }} employee{{ total|pluralize }} {% endwith %}
- csrf_token
这个标签用于跨站请求伪造保护。
在页面的form表单里面写上{% csrf_token %}
注意:
Django的模板语言中属性的优先级大于方法
def xx(request): d = {"a": 1, "b": 2, "c": 3, "items": "100"} return render(request, "xx.html", {"data": d})
如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items并且还有默认的 d.items() 方法,此时在模板语言中:
{{ data.items }}
默认会取d的items key的值
自定义标签,过滤器
必须做的三件事:
1.在应用名下新建一个名为templatetags文件夹(必须叫这个名字) 2.在该新建的文件夹内新建一个任意名称的py文件 3.在该py文件中需要固定写下面两句代码 from django import template register = template.Library()
上面创建的.py文件中:
@register.filter def filter_multi(v1,v2): return v1 * v2 <br> @register.simple_tag def simple_tag_multi(v1,v2): return v1 * v2 <br> @register.simple_tag def my_input(id,arg): result = "<input type='text' id='%s' class='%s' />" %(id,arg,) return mark_safe(result)
在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py
{% load my_tags %}
使用simple_tag和filter(如何调用)
{% load my_tag %} # num=12 {{ num|filter_multi:2 }} #24 {{ num|filter_multi:"[22,333,4444]" }} {% simple_tag_multi 2 5 %} 参数不限,但不能放在if for语句中 {% simple_tag_multi num 5 %}
注意:filter可以用在if等语句后,simple_tag不可以
{% if num|filter_multi:30 > 100 %}
{{ num|filter_multi:30 }}
{% endif %}
模板导入与继承
- 母板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> {% block page-css %} {% endblock %} </head> <body> <h1>这是母板的标题</h1> {% block page-main %} {% endblock %} <h1>母板底部内容</h1> {% block page-js %} {% endblock %} </body> </html>
注意:我们通常会在母板中定义页面专用的CSS块和JS块,方便子页面替换。
- 继承母版
{% extends 'layouts.html' %}
- 块
通过在母板中使用{% block xxx %}来定义"块"。
在子页面中通过定义母板中的block名来对应替换母板中相应的内容。
{% block page-main %} <p>世情薄</p> <p>人情恶</p> <p>雨送黄昏花易落</p> {% endblock %}
- 组件
可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可
{% include 'navbar.html' %}
静态文件相关
-
{% static %}
{% load static %} <img src="{% static "images/hi.jpg" %}" alt="Hi!" /> # 引用JS文件时使用: {% load static %} <script src="{% static "mytest.js" %}"></script> # 某个文件多处被用到可以存为一个变量 {% load static %} {% static "images/hi.jpg" as myphoto %} <img src="{{ myphoto }}"></img>
-
{% get_static_prefix %}
{% load static %} <img src="{% get_static_prefix %}images/hi.jpg" alt="Hi!" /> # 或者 {% load static %} {% get_static_prefix as STATIC_PREFIX %} <img src="{{ STATIC_PREFIX }}images/hi.jpg" alt="Hi!" /> <img src="{{ STATIC_PREFIX }}images/hi2.jpg" alt="Hello!" />
inclusion_tag
多用于返回html代码片段
示例(跟前面的自定义标签一样都需做三件事):
templatetags/my_inclusion.py
from django import template register = template.Library() @register.inclusion_tag('result.html') def show_results(n): n = 1 if n < 1 else int(n) data = ["第{}项".format(i) for i in range(1, n+1)] return {"data": data}
templates/result.html
<ul>
{% for choice in data %}
<li>{{ choice }}</li>
{% endfor %}
</ul>
templates/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>inclusion_tag test</title> </head> <body> {% load my_inclusion %} {% show_results 10 %} </body> </html>