django之模板层
模板语法之变量
在django模板中遍历复杂的数据结构的关键是句点字符,语法: {{ 变量名}}
views.py
from django.shortcuts import render, # Create your views here. def index(request): name = 'xcc' age = 18 l1 = [1, 2, 3, 'xcc'] l2 = [] l3=[1,2,None,3] tu = (1, 2, 3) dic = {'name': 'xcc', 'age': 18, 'l1': [1, 2, 3]} # 函数 def test(): print('xcc') return '张煜是傻逼' print(test()) class Person(): def __init__(self, name, age): self.name = name self.age = age def get_name(self): return self.name @classmethod #绑定给类的 def cls_test(self): return 'cls' @staticmethod # 静态的 def static_test(): return 'static' xcc = Person('xcc', 18) egon = Person('egon', 18) person_list = [xcc, egon] file_size=1024 import datetime ctim=datetime.datetime.now() h1='<h1>您好</h1>' # user='xcc' # 输出:退出 user='' # 输出:登录,注册 # locals() return render(request, 'index.html', locals())
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <hr> {#相当于print了该变量#} <h1>模板语言之变量</h1> <p>字符串:{{ name }}</p> <p>数字:{{ age }}</p> <p>列表:{{ l1 }}</p> <p>元祖:{{ tu }}</p> <p>字典:{{ dic }}</p> {#只写函数名:相当于函数名(),执行该函数#} <p>函数:{{ test }}</p> {#对象内存地址#} <p>对象:{{ xcc }}</p> <p>列表套对象:{{ person_list }}</p> <hr> <h1>深度查询</h1> <p>列表第0个值:{{ l1.0 }}</p> <p>列表第3个值:{{ l1.3 }}</p> <p>字典取值:{{ dic.name }}</p> <p>字典取列表值:{{ dic.l1 }}</p> {#继续取值继续点#} <p>对象取数据属性:{{ xcc.name }}</p> <p>对象取数据属性:{{ xcc.age }}</p> <p>对象取绑定给对象的函数属性:{{ xcc.get_name }}</p> <p>对象取绑定给类的函数属性:{{ xcc.cls_test }}</p> <p>对象取静态方法:{{ xcc.static_test }}</p> <p>把对象列表中egon的年龄取出:{{ person_list.1.age }}</p> <p>字符串的方法:{{ name.upper }}</p> <hr> <h1>模板语言之过滤器</h1> {# 后面就是个python的函数,| 前面的是函数的第一个函数,冒号后面的是第二个参数 #} <p>统计字符串长度:{{ name | length }}</p> <p>统计列表长度:{{ l1 | length }}</p> <p>数字长度:{{ age | length }}</p> <p>过滤器之默认值:{{ l1 | default:'没有值' }}</p> <p>过滤器之默认值:{{ l2 | default:'没有值' }}</p> {# 102400 转化为文件的大小#} <p>过滤器之filesizeformat--0:{{ 102400 |filesizeformat }}</p> <p>过滤器之filesizeformat--1:{{ file_size |filesizeformat }}</p> <p>过滤器之用safe:{{ h1 | safe }}</p> <p>过滤器之不用safe:{{ h1 }}</p> <p>过滤器之truncatewords:{{ '我 dafd dfaf gadfgaasdgadgfadaf'|truncatewords:5 }}</p> <p>过滤器之truncatechars:{{ 'dafddfafgadfgaasdgadgfadaf'|truncatechars:5 }}</p> <p>过滤器之不用safe:{{ h1 }}</p> <p>过滤器之不用date:{{ ctim }}</p> <p>过滤器之用date:{{ ctim | date:'Y-m-d' }}</p> {#从第二个取,倒数第二个#} {#<p>过滤器之slice:{{ l1 |slice:'2:-1' }}</p> #} {#<p>过滤器之slice:{{ l1 |slice:'1:-1' }}</p>#} {# [2, 3]#} <p>过滤器之slice:{{ l1 |slice:'0:-1' }}</p> {#[1,2,3]#} {# 支持步长#} <p>过滤器之slice-字符串:{{ name |slice:'0:3:3' }}</p> {#xcc#} <hr> <h1>模板语言之标签</h1> {#{% for foo in l1 %}#} {# {{ forloop }}<p>#} {# {{ forloop.first }}--->{{ forloop.counter }}---->{{ forloop.revcounter }}--->{{ foo }}</p>#} {#{% endfor %}#} {% for foo in l1 %} {# person_list里面有两个值,所以循环2次#} {% for i in person_list %} {# 取出外层是第几次循环 #} {{ forloop.parentloaop.counter }} <p>{{ forloop.first }}--->{{ forloop.counter }}---->{{ forloop.revcounter }}--->{{ foo }}</p> {% endfor %} {% endfor %} {#循环的对象为空 #} {#{% for foo in l2 %}#} {#{% for foo in dic.values %}#} {#只循环字典的话,取到的是key的值#} {#{% for foo in dic %}#} {#{% for k, foo in dic.items %}#} {# <p>{{ k }}--->{{ foo }}</p>#} {# {% empty %}#} {# 傻逼了#} {#{% endfor %}#} {#{% if user %}#} {# <a href="">退出</a>#} {# {% else %}#} {# <a href="">登录</a>#} {# <a href="">注册</a>#} {#{% endif %}#} {% for foo in l1 %} {% if forloop.first %} <p>第一次的我</p> {% elif forloop.last %} <p>最后的我</p> {% else %} <p>{{ foo }}</p> {% endif %} {% endfor %} {#************ for ,if 都要有结束#} <hr> <h1>自定义标签过滤器</h1> {% load mytags %} <p>{{ 'xcc'|yyy:'nb' }}</p> <h4>使用自定义标签</h4> {# 不能用于if判断 #} <p>{% add_nb 'egon' %}</p> <p>{% add_3 'egon' 'is' 'dsb' %}</p> <hr> {# 过滤器可以用在if判断中 #} {% if 'xcc'|yyy:'nb' %} <p>肯定是True</p> {% endif %} {#标签不能用在if判断中#} </body> </html>
注意:句点符也可以用来引用对象的方法(无参数的方法)
<h4>字典:{{dic.name.upper }}</h4>
模板只过滤器
语法:
{{obj | filter_name:param}} 变量名字 | 过滤器名称:变量
default
如果一个变量是false或者 为空,使用给定的默认值。否则,使用变量的值。例如:
{{ value|default:"nothing" }} #value为变量名
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" }}
slice
如果 value="hello world" {{ value|slice:"2:-1" }}
truncatechars
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。
参数:要截断的字符数
{{ value|truncatechars:4 }}
safe
Django的模板中会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:
value="<a href="">点击</a>" {{ value|safe}}
其它过滤器了解
过滤器 | 描述 | 示例 |
upper | 以大写方式输出 | {{ user.name | upper }} |
add | 给value加上一个数值 | {{ user.age | add:”5” }} |
addslashes | 单引号加上转义号 | |
capfirst | 第一个字母大写 | {{ ‘good’| capfirst }} 返回”Good” |
center | 输出指定长度的字符串,把变量居中 | {{ “abcd”| center:”50” }} |
cut | 删除指定字符串 | {{ “You are not a Englishman” | cut:”not” }} |
date | 格式化日期 | |
default | 如果值不存在,则使用默认值代替 | {{ value | default:”(N/A)” }} |
default_if_none | 如果值为None, 则使用默认值代替 | |
dictsort | 按某字段排序,变量必须是一个dictionary | {% for moment in moments | dictsort:”id” %} |
dictsortreversed | 按某字段倒序排序,变量必须是dictionary | |
divisibleby | 判断是否可以被数字整除 |
{{ 224 | divisibleby:2 }} 返回 True |
escape | 按HTML转义,比如将”<”转换为”<” | |
filesizeformat | 增加数字的可读性,转换结果为13KB,89MB,3Bytes等 |
{{ 1024 | filesizeformat }} 返回 1.0KB |
first | 返回列表的第1个元素,变量必须是一个列表 | |
floatformat | 转换为指定精度的小数,默认保留1位小数 | {{ 3.1415926 | floatformat:3 }} 返回 3.142 四舍五入 |
get_digit | 从个位数开始截取指定位置的数字 | {{ 123456 | get_digit:’1’}} |
join | 用指定分隔符连接列表 | {{ [‘abc’,’45’] | join:’*’ }} 返回 abc*45 |
length | 返回列表中元素的个数或字符串长度 | |
length_is | 检查列表,字符串长度是否符合指定的值 | {{ ‘hello’| length_is:’3’ }} |
linebreaks | 用<p>或<br>标签包裹变量 | {{ “Hi\n\nDavid”|linebreaks }} 返回<p>Hi</p><p>David</p> |
linebreaksbr | 用<br/>标签代替换行符 | |
linenumbers | 为变量中的每一行加上行号 | |
ljust | 输出指定长度的字符串,变量左对齐 | {{‘ab’|ljust:5}}返回 ‘ab ’ |
lower | 字符串变小写 | |
make_list | 将字符串转换为列表 | |
pluralize | 根据数字确定是否输出英文复数符号 | |
random | 返回列表的随机一项 | |
removetags | 删除字符串中指定的HTML标记 | {{value | removetags: “h1 h2”}} |
rjust | 输出指定长度的字符串,变量右对齐 | |
slice | 切片操作, 返回列表 | {{[3,9,1] | slice:’:2’}} 返回 [3,9]{{ 'asdikfjhihgie' | slice:':5' }} 返回 ‘asdik’ |
slugify | 在字符串中留下减号和下划线,其它符号删除,空格用减号替换 |
{{ '5-2=3and5 2=3' | slugify }} 返回 5-23and5-23 |
stringformat | 字符串格式化,语法同python | |
time | 返回日期的时间部分 | |
timesince | 以“到现在为止过了多长时间”显示时间变量 | 结果可能为 45days, 3 hours |
timeuntil | 以“从现在开始到时间变量”还有多长时间显示时间变量 | |
title | 每个单词首字母大写 | |
truncatewords | 将字符串转换为省略表达方式 |
{{ 'This is a pen' | truncatewords:2 }}返回 This is ... |
truncatewords_html | 同上,但保留其中的HTML标签 |
{{ '<p>This is a pen</p>' | truncatewords:2 }}返回 <p>This is ...</p> |
urlencode | 将字符串中的特殊字符转换为url兼容表达方式 | {{ ‘http://www.aaa.com/foo?a=b&b=c’ | urlencode}} |
urlize | 将变量字符串中的url由纯文本变为链接 | |
wordcount | 返回变量字符串中的单词数 | |
yesno | 将布尔变量转换为字符串yes, no 或maybe |
{{ True | yesno }} 返回 yes no maybe |
for标签
遍历每一个元素:
{% for person in person_list %} <p>{{ person.name }}</p> {% endfor %}
遍历一个字典
{%for foo in dic %} # 只循环字典,取到的是 key 值
{% for foo in dic.values %} #循环的是value值
{% 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
for标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。
{% for person in person_list %} <p>{{ person.name }}</p> {% empty %} <p>sorry,no person here</p> {% endfor %}
自定义标签和过滤器
1、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.
2、在app中创建templatetags模块(模块名只能是templatetags)
3、创建任意 .py 文件,如:my_tags.py
from django import template from django.utils.safestring import mark_safe register = template.Library() #register的名字是固定的,不可改变 @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)
4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py
{
%
load my_tags
%
}
5、使用simple_tag和filter(如何调用)
-------------------------------.html {% load xxx %} # 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 %}