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文件进行模板渲染,如果你图省事,你可以用它,但是很多多余的变量也被传进去了,效率低
模板:
{{s}}
列表:{{ l.0 }}
列表:{{ l.2 }}
字典:{{ dic.name }}
日期:{{ date.year }}
类对象列表:{{ person_list.0.name }}
类对象列表:{{ person_list.0.dream }}
注意: 调用对象里面的方法的时候,不需要写括号来执行,并且只能执行不需要传参数的方法,如果你的这个方法需要传参数,那么模板语言不支持,不能帮你渲染
js代码中使用模板:
# 我们直接在js代码中使用模板语法的时候,模板渲染的时候会有个转义的动作, # 将s = ['哈哈','xx']这种数据中的元素的引号变为一个特殊符号:
三、过滤器
在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%}
{{ person.name}}
{% endfor%}
# 可以利用{% for obj in list reversed %}反向完成循环。
遍历一个字典:
{% for key,val in dic.items %}
{{ key }}:{{ val }}
{% 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 %}
{{ person.name }}
{% empty %}
sorry,no person here
{% endfor %}
2、if标签
{% if user_list|length > 5%}
七座豪华suv
{% else %}
黄包车
{% endif%}
3、with
# 使用一个简单地名字缓存一个复杂的变量,多用于给一个复杂的变量起别名
{% with total=business.employees.count %}
{{ total }}
{% endwith %}
{% with business.employees.count as total %}
{{ total }}
{% endwith %}
五、模板继承
模板继承可以创建一个基本的骨架模板,包括站点的全部元素,并且可以定义能被子模板覆盖的blocks
index2.html 母版
{#做一个首页一样的页面#}
class="outer">
class="nav">标题
class="left">
class="content">
{% block content %}
class="hh">WELCOME TO LOGIN
{% endblock %}
{# WELCOME TO LOGIN
#}
继承母版
{#继承 母版 母版就是index2.html#}
{% extends "index2.html" %}
{% load staticfiles %}
{% block content %}
{# 这里把继承过来的class=content重写了,但是还想用父类里的#}
{{ block.super }}
{% for student in student_list %}
学生{{ student }}
{% endfor %}
{% include "include_在模板中添加模板.html" %}
{% endblock %}
{#1.如果在模板中使用 {% extends %} ,必须保证其为模板中的第一个模板标记。否则,模板继承将不起作用。#}
{#2.一般来说,基础模板中的{% block %} 标签越多越好。记住,子模板不必定义模板中所有的代码块,因此你可以#}
{#用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码进行(重)定义。俗话说,钩子越多越好#}
{#3.如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个{% block %} 中。#}
{# 如果你需要访问父模板中的块的内容,使用{{ block.super }}这个标签吧。这一个魔法变量将会表现出#}
{# 父模板中的内容。如果只想在上级代码基础上添加内容,而不是全部重载,该变量就显得非常有用了。#}
{#4.不允许在同一个模板中定义多个同名的{% block %} 。 存在这样的限制是因为block 标签的工作方式是双向的。#}
{# 也就是说,block 标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现#}
{# 了两个相同名称 {% block %} 标签,父模板将无从得知要使用哪个块的内容。#}
六、组件
可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方,文件的任意位置按如下语法导入即可。
{% include 'navbar.html' %}
例:
有如下导航栏:
"en"> "UTF-8">Title
嵌入到 test.html
"en"> "UTF-8">Title {% include 'nav.html' %}xxxxxxxxxx
组件和插件的区别:
""" 组件是提供某一完整功能的模块,如:编辑器组件,QQ空间提供的关注组件 等 而插件更倾向封闭某一功能方法的函数 这两者的区别在 javascript 里面区别很小,组件这个名词用的不多,一般统称插件 """
七、静态文件相关
前端页面引入静态文件的写法,因为别名也可能会修改,所以使用路径的时候通过load static来找到别名,通过别名映射路径的方式来获取惊天文件
某个文件多处被用到可以存为一个变量
{% load static %}
{% static 'images/hi.jpg' as mypyoto%}
'{{ myphoto }}'>
form表单等路径问题: