这篇文章用于记录Django视图相关知识,发现有需要补充的会随时添加
仅用于记录,以后方便自己查阅,至于大家能不能看懂,我觉得随缘就行。
一、模板使用流程
加载
tem = loader.get_template(‘xxx.html’)
内容字典
context = RequestContent(request,{})
渲染
return render(tem.render(context))
简写形式:
context = {}
return render(request,’xxx.html’,context)
二、模板语言DTL
了解下DTL(Django Templates Langage)
就是{{ name }} {%for in %}…{%end for%}在HTML这样式的就是DTL,也就是模板语言
其中包括
- 变量
- 标签{%代码块%}
- 过滤器
- 注释{#代码或者HTML#}
1、变量
{{ value }}
- 当模板引擎遇到了一个变量的时候,会计算这个变量,然后将结果输出
- 变量的名称必须有字母、数字、下划线(不能开头)和点组成
- 当模板引擎遇到点(.)的时候,会按照一下顺序查询:
字典:foo[‘bar’]
属性或方法:foo.bar
按照数字索引:foo[bar] - 如果变量不存在,模板引擎认定其为空字符串
- 在模板中不能传递参数
以{{book.id}}为例
首先会把book当成字典,查找book[‘id’]的值
如果查找失败,
就会把book当做一个对象,去查找book.id的值
如果查找还是失败了
就会把book当做一个列表或者元组,去查找book[id]的值
如果还是失败了
就会{{book.id}}看成 “” 空字符串
在模板内不能使用带参数的方法,因为在变量中,是不能使用()的,所以也就不能往方法里写对应的参数
2、标签
- 语法:{%tag%}
- 作用
在输出中创建文本
控制循环或者逻辑
加载外部信息到模板中供之后的变量使用
(1)for标签
使用forloop.counter可以返回当前循环是第几次
{% for... in... %}
循环逻辑
循环计数,从1开始,从0开始
{{ forloop.counter/forloop.counter0 }}{{xxxx}}
{% empty %}
循环为空,执行的代码
{% end for%}
(2)if 标签
{% if... %}
逻辑1
{{% elif...%}}
逻辑2
{%else%}
逻辑3
{% endif%}
(3)comment 注释标签
{%comment %}
注释内容
{% endcomment %}
(4)include标签
{%include "foo/bar.html" %}
(5)url标签
{%url 'name' p1 p2 %}
(6)csrf_token:这个标签用于跨站请求伪造保护
(7)布尔标签:and 、or,and优先级高于or
(8)block、extends用于模板继承
(9)autoescape用于HTML转义
3、过滤器 |
- 语法:{{变量|过滤器}}
- 使用管道符号
- 通过过滤器改变变量计算结果
- 可以在if标签中使用
{% if list1|length > 1 %}
- 过滤器可以进行串联
name|lower|upper
- 过滤器可以传递参数
list|join:","
- 提供默认值,如果一个变量没有查询到,按照规定应该被模板引擎认为是空字符串,可以通过过滤器设置默认值
value|default:"默认值"
- date:根据给定格式,对一个date进行格式化
4、注释
- 单行注释{# 注释内容 #}
- 多行注释使用{%comment%} 注释内容 {%endcomment%}
三、反向解析
动态生成url,不需要硬编码,利于以后维护
目前了解,在a标签中写的跳转地址用绝对地址的时候,当总url地址更改的时候,造成了大量的工作,加大了维护的成本,如果使用相对地址,就不存在这个问题
情景是这样的
我们要做一个页面跳转
总URL地址
path('day/', include('day20180510.urls', namespace="day20180510"))
分URL地址
path(r'showa/', showA),
path(r'showb/', showB)
在showA中返回的模板中添加a标签,用绝对地址就写跳转地址
绝对路径:<a href="/day/showb">跳转到B</a>
相对路径:<a href="../showb">跳转到B</a>
在使用绝对路径的时候如果总URL地址不再是day/,而改成d/,那么分URL内的所有跳转地址会全部报错,当然使用相对路径不会出错。
在这个情境下,我们才会使用反向解析
将路径写为{% url 'day20180510:showB' ('参数1' '参数2') %},
顺便在分URL中与urlpatterns同级的地方写入
app_name = day20180510
这样就不会有问题了,根据你写的url地址反向解析出地址填入地址栏
至于参数的问题:
如果要跳转的地址是path(r'<int:year>/', showB)
这时候showB方法就需要有个year参数传入
我直接使用绝对地址的时候是这样的
<a href="/day/1991">跳转到B</a>
那我们用反向解析的方法就需要这么写
<a href="{% url 'day20180510:showB' '1991' %}">跳转到B</a>
如果是两个参数就依次往后写就好了,相对应的showB方法的传入参数也要依次增加,并且一一对应
template 加参数,url 加参数 ,view 加参数 三位一体
四、模板继承
1、基础使用
一般情况下,多个网页,网页头相同,网页尾相同,只有网页中间内容不同,这时候我们不能每一个页面都写头尾吧。那不累死
鉴于这种情况我们就需要利用模板继承了。
只需要两个标签
{% block xxx %}
{% endblock %}
和
{% extends '父模板' %}
新建父模板base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>top</h1>
<hr>
{% block middle %}
中间内容
{% endblock %}
<hr>
<h1>bottom</h1>
</body>
</html>
新建子模板index.html
{% extends 'day20180510/base.html' %}
{% comment %}
注意这里没有H5的格式
直接进行继承和block内容编写
还有一个注意点extends标签必须放在第一行
如果把这里的block注释掉就会显示'我是base'
如果加上就会显示'我是index'
{% endcomment %}
{% block middle %}
我是index
{% endblock middle %}
2、多层继承
一般情况下,我们使用三层继承就够了
base - user - usercenter为例
base
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>base</title>
{% block top %}
{% endblock %}
</head>
<body>
logo
<hr>
{% block middle %}
base
{% endblock %}
</body>
<hr>
bottom
</html>
user
{% extends 'day20180517/base.html' %}
{% block middle %}
<table border="1">
<tr>
<td height="300">
用户导航
</td>
<td>
{% block user_right %}
{% endblock %}
</td>
</tr>
</table>
{% endblock %}
usercenter
{% extends 'day20180517/base_user.html' %}
{% block user_right %}
用户中心
{% endblock %}
注意在usercenter既可以实现user中的block user_right 也可以实现base中的block middle(在实现middle的时候 就算实现了block user_right 也不会生效 ),当然也可以实现在base中声明而没有在user中实现的block top
一般来讲3层就基本上够用了。不用可以追求层数。
还有一点,在子模板中,有个参数比如说是uname,但是他没有在子模板中显示,显示的代码{{uname}} 放在了父模板中,也是可以实现的,从这一点我们可以看出,子模板的展示,实质上是把所以祖先模板结合起来然后进行显示的,这样祖先模板中有子模板中的参数的显示代码,就会显示出来。
四、HTML转义
转义的字符:
< 会转换为 <
> 会转换为 >
' (单引号) 会转换为 '
" (双引号) 会转换为 "
& 会转换为 &
如果我们的参数中有HTML标签的话就像这样
视图views
def index(request):
context = {'s': '<h1>我是h1</h1>'}
return render(request, "day20180517/index.html", context)
模板index
{% extends 'day20180517/base.html' %}
{% block middle %}
欢迎使用!
<br>
{{ s }}
{% endblock %}
再看源代码
这就尴尬了,本来想大写标题的怎么就给直接显示出来了呢?
原来是因为我们使用参数的时候,它默认这个变量不安全,会进行转义
我们写的{{ s }} 就被变成了 {{ s|escape }}
当我们想让他标题放大的时候,我们手动告诉浏览器这个参数是安全的
{{ s|safe }}就可以了
或者这样写也是可以的
{% autoescape off %}
{{ s }}
{% endautoescape %}
还有一点需要注意,这个参数带这HTML标签穿过来了,会自动转义,那么如果是直接写在HTML中的默认参数中带标签呢?
像这样
{{ y|default:'<h1>你好,我是y<h1>'}}
y参数不存在所以,肯定显示default
我们没有进行逆转义过程,就被正常显示了,由此可见我们只有参数中的HTML标签会被自动转义,而直接写在HTML中的标签是不会自动被转义的
那如果我们想让他转义呢? 答案是 手动转义 自己慢慢一个一个根据上面的字符替换吧。
五、CSRF
PASS