在Django MVC概述和开发流程中已经讲解了Django的MVT开发流程,本文重点对MVT中的模板(Template)进行重点讲解。
模板包含两部分:
- 静态部分: 包含html、css、js。
- 动态部分: 模板语言。
模板变量
模板变量名是由数字、字母、下划线和点组成的,不能以下划线开头。
代码语言:javascript复制{{ 模板变量名 }}
{{ variable.data }}
对variable.data
的解析过程:
- 1.首先把variable当成一个字典,把data当成键名,进行
variable['data']
取值 - 2.然后把variable当成一个对象,把data当成属性,进行
variable.data
取值 - 3.最后把variable当成一个对象,把data当成方法,进行
variable.data()
取方法调用的返回值 - 4.如果以上解析都失败,最后则用空字符串填充模板变量。
常用模板标签
注释
单行注释
代码语言:javascript复制{# 单行注释内容 #}
多行注释
代码语言:javascript复制{% comment %}
多行注释内容1
多行注释内容2
多行注释内容3
{% endcomment %}
for循环
代码语言:javascript复制{% for x in list %}
{# 从list中取值赋给x,同python的for #}
{# ... #}
{# 可以通过{{ forloop.counter }}得到for循环遍历到第几次了,计数值从1开始。#}
{{ forloop.counter }}
{% empty %}
{# 如果列表为空时执行的语句 #}
{# ... #}
{% endfor %}
if判断
代码语言:javascript复制{% if a > b %}
{# ... #}
{% elif a > c %}
{# ... #}
{% else %}
{# ... #}
{% endif %}
比较操作符:> 、< 、>= 、 <= 、 ==、 != 逻辑运算符:not 、 and 、 or 注:进行比较操作时,操作符两边必须有空格。
过滤器
过滤器在模板中是放在模板变量后用于对模板变量进行操作的技术。变量与过滤器之间通过管道符号“|”连接,使用格式如下
代码语言:javascript复制{{ 模板变量 | 过滤器: 参数}}
Django内置过滤器的详细介绍参考Django 1.8.2 中文文档。
模板继承
模板继承使得开发者可以将多个页面共有部分抽取出来放在一个模板文件中,然后其他模板继承该模板来共享该共有部分。
代码语言:javascript复制父模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{# 在父模板中可以定义块来占位,子模板可以重写这个块 #}
<title>{% block title %} parent {% endblock %}</title>
</head>
<body>
<h1>头部</h1>
{# 在父模板中可以定义块来占位,子模板可以重写这个块 #}
{% block body %}
<p>我是父模板</p>
{% endblock body%}
<h1>尾部</h1>
</body>
</html>
代码语言:javascript复制子模板
{# 子模板继承父模板 #}
{% extends "school_test/parent.html" %}
{# 重写父模板中某一块的内容 #}
{% block title %}
children
{% endblock title %}
{% block body %}
{# 获取父模板中块的默认内容 #}
父模板中的内容: {{ block.super }}
子模板中的内容:<p>我是子模板</p>
{% endblock body %}
转义
在视图中传递过来的字符串会自动转义,如果要关闭转移使用如下模板语法
代码语言:javascript复制{{ 模板变量 | safe }}
或者对多行关闭转义
代码语言:javascript复制{% autoescape off %}
{# 需要关闭转义的内容1 #}
{# 需要关闭转义的内容2 #}
{# 需要关闭转义的内容3 #}
{% endautoescape %}
注:模板硬编码中的字符串默认不会经过转义,如果需要转义,则必须手动进行转义。
CSRF
CSRF(Cross-site request forgery)跨站请求伪造,csrf攻击者在用户已经登录目标网站之后,诱使用户访问一个攻击页面,利用目标网站对用户的信任,以用户身份在攻击页面对目标网站发起伪造用户操作的请求,达到攻击目的。
Django默认开启了csrf中间件来防御csrf攻击,所以当发送post请求时会返回403错误,而开发者访问本站点的网页时同样会返回403错误,所以在Django MVT之V中直接注释掉了csrf防御。
为了防止csrf攻击,需要打开csrf中间件。(注意:默认情况下,Django已经打开)
但是开启了csrf防御后,请求本站点页面也会返回403错误,解决办法是使用csrf_token标签
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆</title>
</head>
<body>
<form action="/login_handle" method="post">
{# 加入csrf验证的隐藏域 #}
{% csrf_token %}
账号 <input type="text" name="username" value="{{ username }}"> <br>
密码 <input type="password" name="password" value="{{ password }}"> <br>
<input type="checkbox" name="check"> 记住用户名和密码 <br>
<input type="submit" value="登陆">
</form>
</body>
</html>
csrf_token防御原理:
当启用中间件并加入标签csrf_token后,Django框架渲染模板文件时会在页面生成一个名字叫做csrfmiddlewaretoken的隐藏域input元素。并且会向客户端浏览器中写入一条Cookie信息,这条信息的值与隐藏域input元素的value属性是一致的。当post请求提交到服务器后,会先由csrf中间件进行对比验证,如果验证失败则返回403错误,而不会进行后续的处理。
URL反向解析
Django除了提供了从URL到视图函数的映射,还提供了反向的从映射名到URL的解析功能。使用URL反向解析可以动态生成URL,当URL变化时,不需要手动去更改。
修改项目下的urls.py的urlpatterns,用namespace指定反向解析时的项目名。
代码语言:javascript复制urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
# namespace='school_test'指定反向解析时的项目名为school_test
url(r'^', include('school_test.urls', namespace='school_test')),
]
修改应用下的urls.py的urlpatterns,用name指定反向解析时的应用名。
代码语言:javascript复制urlpatterns = [
url(r'^index$', views.index),
url(r'^login$', views.login),
# name='login_handle'指定反向解析时的url名为login_handle
url(r'^login_handle$', views.login_handle, name='login_handle'),
url(r'^login_ajax$', views.login_ajax),
url(r'^login_ajax_handle$', views.login_ajax_handle),
url(r'^children$', views.childern),
]
在模板中使用反向解析,格式为
代码语言:javascript复制{% url 'namespace名字:name' %}
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆</title>
</head>
<body>
<!-- {% url 'school_test:login_handle' %} 使用反向解析 -->
<form action="{% url 'school_test:login_handle' %}" method="post">
{% csrf_token %}
账号 <input type="text" name="username" value="{{ username }}"> <br>
密码 <input type="password" name="password" value="{{ password }}"> <br>
<input type="checkbox" name="check"> 记住用户名和密码 <br>
<input type="submit" value="登陆">
</form>
</body>
</html>
随后渲染模板时,Django框架会自动根据url配置进行替换
在模板中使用反向解析其他格式:
1.带位置参数
代码语言:javascript复制{% url 'namespace名字:name' 参数 %}
2.带关键字参数:
代码语言:javascript复制{% url 'namespace名字:name' 关键字参数=值 %}
在视图中使用反向解析,需要先导入reverse
from django.core.urlresolvers import reverse
- 1.无参数:
reverse('namespace名字 : name名字')
- 2.带位置参数:
reverse('namespace名字:name名字', args = 位置参数构成的元组)
- 3.带关键字参数:
reverse('namespace名字:name名字', kwargs = 关键字参数构成的字典)
本文作者: Ifan Tsai (菜菜)
本文链接: https://cloud.tencent.com/developer/article/2164573
版权声明: 本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!