04.django之模块系统
一、语法
""" {{ }} 和 {% %} 变量相关的用{{}},逻辑相关的用{% %} """
二. 句点号
""" 模板系统遇到点('.'),它将以这样的顺序查询 字典查询(Dictionary lookup) 属性或方法查询(Attribute or method lookup) 数字索引查询(Numeric index lookup) 如果使用的变量不存在,模板系统将插入 string_if_invalid 选项的值 他被默认设置为 ''(空字符串) """
views代码:
def index(request): import datetime s = "hello" l = [111, 222, 333] # 列表 dic = {"name": "yuan", "age": 18} # 字典 date = datetime.date(1993, 5, 2) # 日期对象 class Person(object): def __init__(self, name): self.name = name def dream(self): return 'dreamer' person_aaa = Person("chao") # 自定义类对象 person_bbb = Person("yantao") person_ccc = Person("jinxin") person_list = [person_aaa, person_bbb, person_ccc] return render(request, "index.html", {"l": l, "dic": dic, "date": date, "person_list": person_list}) # return render(request,'index.html',locals()) #locals()获取函数内容所有的变量,然后通过render方法给了index.html文件进行模板渲染,如果你图省事,你可以用它,但是很多多余的变量也被传进去了,效率低
模板:
<h4>{{s}}</h4>
<h4>列表:{{ l.0 }}</h4>
<h4>列表:{{ l.2 }}</h4>
<h4>字典:{{ dic.name }}</h4>
<h4>日期:{{ date.year }}</h4>
<!--取列表的第1个对象的name属性的值-->
<h4>类对象列表:{{ person_list.0.name }}</h4>
<!--取列表的第1个对象的dream方法的返回值,如果没有返回值,拿到的是none-->
<h4>类对象列表:{{ person_list.0.dream }}</h4>
注意:
调用对象里面的方法的时候,不需要写括号来执行,并且只能执行不需要传参数的方法,如果你的这个方法需要传参数,那么模板语言不支持,不能帮你渲染
js代码中使用模板:
# 我们直接在js代码中使用模板语法的时候,模板渲染的时候会有个转义的动作, # 将s = ['哈哈','xx']这种数据中的元素的引号变为一个特殊符号:
<script> // 不加safe的话,引号会被转义。 // var a = {{ s }} // var a = ['哈哈', 'xx']; // console.log(a[0]) // 加上safe就正常了 var a = {{ s|safe }}; console.log(a[0]) // 还要注意,当我们模板渲染的时候,后端返回的数据是字符串的话,我们需要将{{ s }}外面加上引号 比如s = '哈哈' js中的写法 var a = '{{ s }}' </script>
三、过滤器
在django的模板语言中,通过使用过滤器 来改变变量的显示
注意:
1.过滤器支持'链式'操作,即一个过滤器的输出作为另一个过滤器的输入
2.过滤器可以接受参数,列如: {{sss|truncatewords:30}},这将显示sss的前30个词,
3.过滤器参数包括空格的话,必须用引号包裹起来,比如使用逗号和空格去连接一个列表中的元素, 如{{list|join:','}}
4.'|'左右没有空格没有空格没有空格
1、default
# 如果一个变量是false或者为空,使用给定的默认值.否则,使用变量的值
{{ value|default:'nothing'}}
2、length
# 返回值的长度,作用域字符串和列表
{{value|length}} # 返回value的长度,如 value=['a','b','c','d']的话,就显示4
3、filesizeformat
{{ value|filesizeformat }} # 将值格式化为一个 “人类可读的” 文件尺寸 (例如 '13 KB', '4.1 MB', '102 bytes', 等等)。例如
4、slice
{{value|slice:"2:-1"}} # 切片,如果 value="hello world",还有其他可切片的数据类型
5、date
{{ value|date:"Y-m-d H:i:s"}} # 格式化,如果 value=datetime.datetime.now()
6、safe
Django的模板中在进行模板渲染的时候会对HTML标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全,django担心这是用户添加的数据,比如评论的时候写了一段js代码,这个评论一提交,js代码就执行啦,如果写个弹窗的死循环,就一直弹框,叫xss攻击,所以浏览器不让你这么搞,给你转义了。
但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。
7、truncatechars
{{ value|truncatechars:9}} #注意:最后那三个省略号也是9个字符里面的,也就是这个9截断出来的是6个字符+3个省略号,有人会说,怎么展开啊,配合前端的点击事件就行啦 # 如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾
8、truncatewords
{{ value|truncatewords:3}} #上面例子得到的结果是 'hello girl h1...' # 在一定数量的字后截断字符串,是截多少个单词。 # 例如:‘hello girl hi baby yue ma’,
9、cut
{{ value|cut:' ' }} # 移除value中所有的与给出的变量相同的字符串 # 如果value为'i love you',那么将输出'iloveyou'.
10、join
{{ list|join:', ' }} # 使用字符串连接列表,{{ list|join:', ' }},就像Python的str.join(list)
四、标签tags
1.for标签
# for 循环每一个元素,for+TAB生成for循环结构,复杂一些功能需要通过js
{% for key,val in person_list%} <p>{{ person.name}}</p> <!--凡是变量都要用两个大括号括起来--> {% endfor%}
# 可以利用{% for obj in list reversed %}反向完成循环。
遍历一个字典:
{% for key,val in dic.items %} <p>{{ key }}:{{ val }}</p> {% endfor %} # 注:循环序号可以通过{{forloop}}显示,必须在循环内部用
forloop.counter 当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能
forloop.counter0 当前循环的索引值(从0开始)
forloop.revcounter 当前循环的倒序索引值(从1开始)
forloop.revcounter0 当前循环的倒序索引值(从0开始)
forloop.first 当前循环是不是第一次循环(布尔值)
forloop.last 当前循环是不是最后一次循环(布尔值)
forloop.parentloop 本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等
for ... empty
for 标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。
{% for person in person_list %} <p>{{ person.name }}</p> {% empty %} <p>sorry,no person here</p> {% endfor %}
2、if标签
{% if user_list|length > 5%} 七座豪华suv {% else %} 黄包车 {% endif%}
3、with
# 使用一个简单地名字缓存一个复杂的变量,多用于给一个复杂的变量起别名
{% with total=business.employees.count %} {{ total }} <!--只能在with语句体内用--> {% endwith %}
或
{% with business.employees.count as total %}
{{ total }}
{% endwith %}
五、模板继承
模板继承可以创建一个基本的骨架模板,包括站点的全部元素,并且可以定义能被子模板覆盖的blocks
index2.html 母版
{#做一个首页一样的页面#} <div class="outer"> <div class="nav">标题</div> <div class="left"> <div class="student manage"><a href="/student">学生管理</a></div> <div class="teacher manage"><a href="">老师管理</a></div> <div class="course manage"><a href="">课程管理</a></div> <div class="classes manage"><a href="">班级管理</a></div> </div> <div class="content"> {% block content %} <h1 class="hh">WELCOME TO LOGIN</h1> {% endblock %} {# <h1 class="hh">WELCOME TO LOGIN</h1>#} </div> </div>
继承母版
{#继承 母版 母版就是index2.html#} {% extends "index2.html" %} {% load staticfiles %} {% block content %} {# 这里把继承过来的class=content重写了,但是还想用父类里的<h1>#} {{ block.super }} {% for student in student_list %} <h2>学生{{ student }}</h2> {% endfor %} {% include "include_在模板中添加模板.html" %} {% endblock %} {#1.如果在模板中使用 {% extends %} ,必须保证其为模板中的第一个模板标记。否则,模板继承将不起作用。#} {#2.一般来说,基础模板中的{% block %} 标签越多越好。记住,子模板不必定义模板中所有的代码块,因此你可以#} {#用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码进行(重)定义。俗话说,钩子越多越好#} {#3.如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个{% block %} 中。#} {# 如果你需要访问父模板中的块的内容,使用{{ block.super }}这个标签吧。这一个魔法变量将会表现出#} {# 父模板中的内容。如果只想在上级代码基础上添加内容,而不是全部重载,该变量就显得非常有用了。#} {#4.不允许在同一个模板中定义多个同名的{% block %} 。 存在这样的限制是因为block 标签的工作方式是双向的。#} {# 也就是说,block 标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现#} {# 了两个相同名称 {% block %} 标签,父模板将无从得知要使用哪个块的内容。#}
六、组件
可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方,文件的任意位置按如下语法导入即可。
{% include 'navbar.html' %}
例:
有如下导航栏:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .c1{ background-color: red; height: 40px; } </style> </head> <body> <div class="c1"> <div> <a href="">xx</a> <a href="">dd</a> </div> </div> </body> </html>
嵌入到 test.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {% include 'nav.html' %} <h1>xxxxxxxxxx</h1> </body> </html>
组件和插件的区别:
""" 组件是提供某一完整功能的模块,如:编辑器组件,QQ空间提供的关注组件 等 而插件更倾向封闭某一功能方法的函数 这两者的区别在 javascript 里面区别很小,组件这个名词用的不多,一般统称插件 """
七、静态文件相关
前端页面引入静态文件的写法,因为别名也可能会修改,所以使用路径的时候通过load static来找到别名,通过别名映射路径的方式来获取惊天文件
某个文件多处被用到可以存为一个变量
{% load static %} {% static 'images/hi.jpg' as mypyoto%} <img src='{{ myphoto }}'>
form表单等路径问题:
<form action='/login/'></form> <img src='/static/1.jpg' alt=''> 等标签需要写路径的地方,如果写的是相对路径,那么前置的/这个斜杠必须写上 不然这个请求会拼接当前网页的路径来发送请求,就不能匹配我们的后端路径了