首页 > 代码库 > Django中模板总结[模板语言,模板继承,CSRF攻击,反向解析]
Django中模板总结[模板语言,模板继承,CSRF攻击,反向解析]
模板
概述
作为Web框架,Django提供了模板,用于编写html代码,还可以嵌入模板代码更快更方便的完成页面开发,再通过在视图中渲染模板,将生成最终的html字符串返回给客户端浏览器。模版致力于表达外观,而不是程序逻辑。模板的设计实现了业务逻辑view与显示内容template的分离,一个视图可以使用任意一个模板,一个模板可以供多个视图使用。
创建模板文件夹
- 在项目的文件里面定义一个templates文件夹
- 在创建的文件夹里面再创建一个文件夹为每个应用的html文件夹 起名为和应用名同名的文件名
- 去setting.py中添加配置一下文件路径 找到TEMPLATES项
"DIRS":[os.path.jion(DASE_DIR, "templates")]
模板包含两部分:
- 静态部分,包含html、css、js。
- 动态部分,就是模板语言。
Django处理模板分为两个阶段:
- 1.加载:根据给定的路径找到模板文件,编译后放在内存中。
- 2.渲染:使用上下文数据对模板插值并返回生成的字符串。
模板加载的过程
from django.template import loader, RequestContext def index(request): """首页""" # 1.加载模板文件,得到一个模板对象 temp = loader.get_template(‘booktest/index.html‘) # 2.定义模板上下文给模板传数据 context = RequestContext(request, {‘kay‘: ‘kk‘}) # 3.产生生标准的html内容 res_html = temp.render(context) # 4.返回内容给浏览器 return HttpResponse(res_html) -->简写 return render(request, ‘booktest/index.html‘, {‘kay‘: ‘kaykay‘})
模板语言
变量
格式:
- {{模板变量名}}
模板变量名是有数字,字母,下划线和点组成的,不能以下划线开头。
模板变量的解析顺序:
例如:book.title
- 把book当成一个字典,把title当成key,取值book[‘title’]
- 把book当成一个对象,把title当成属性,取值book.title
- 把book当成一个对象,把title当成方法名,取值book.title()
例如:book.0
- 把book当成一个字典,把0当成key,取值book[‘0’]
- 把book当成一个列表,把0当成下标,取值book[0]
注意:如果解析失败,则产生内容时用空字符串填充模板变量。
标签
语法如下:
{%代码段%}
for标签语法如下:
{%for item in 列表%} 循环逻辑 {{forloop.counter}}表示当前是第几次循环,从1开始 {%empty%} 列表为空或不存在时执行此逻辑 {%endfor%}
if标签语法如下:
{%if ...%} 逻辑1 {%elif ...%} 逻辑2 {%else%} 逻辑3 {%endif%}
关系比较操作符:
> < >= <= == !=
注意:进行比较操作是,比较操作符两边必须有空格。
逻辑比较:
not and or
示例:
{% for book in books %} {% if book.id < 3 %} <li class="red">{{ book.btitle }}</li> {% elif book.id == 3 %} <li class="gold">{{ book.btitle }}</li> {% elif book.id > 3 %} <li class="green">{{ book.btitle }}</li> {% endif %} {% endfor %} {% for book in books2 %} {% empty %} <li>流星蝴蝶剑</li> % endfor %}
过滤器
- 使用管道符号|来应用过滤器,用于进行计算、转换操作,可以使用在变量、标签中。
- 如果过滤器需要参数,则使用冒号:传递参数。
- 过滤器用于对模板变量进行操作
语法:
- 变量|过滤器:参数
內建过滤器参数
- date:改变日期的显示格式。
- Y表示年,格式为4位,y表示两位的年。
- m表示月,格式为01,02,12等。
- j表示日,格式为1,2等。
- H表 示时,24进 制,h表示12进制的时。
- i表示分,为0-59。
- s表示秒 ,为0-59。
- 示例:
- value|date:"Y年m月j日 H时i分s秒"
- length:长度length,返回字符串包含字符的个数,列表、元组、字典的元素个数。
- 默认值default,如果变量不存在时则返回默认值。
- data|default:‘默认值‘
更多內建过滤器。http://python.usyiyi.cn/translate/django_182/ref/templates/builtins.html
示例:
{% for book in books %} {% if book.btitle|length < 5 %} <li>{{ book.btitle }}--{{ book.bpub_date|date:‘Y年-m月-j日‘ }}</li> {% else %} <li>{{ book.btitle }}--{{ book.bpub_date }}</li> {% endif %} {% endfor %} {# 使用不存在的模板变量时设置默认值 #} {{ date|default:"hello" }}
自定义过滤器流程
- 在应用的目录里创建templatetags包
- .在包当中定义filter.py文件
示例:
# coding=utf-8 # 引入注册对象 from django.template import Library register=Library() # 使用装饰器进行注册 @register.filter # 定义求余函数mod,将value对2求余 def mod(num): return num%2 == 0 # 带参数的的过滤器 @register.filter def mod(num, val): return num%val == 0
3.在html文件中导入(和内置的过滤器用法相同)
{%load filters%} {% if book.id|mod %} <li class="red">{{ book.btitle }}---{{ book.bpub_date|date:‘Y-m-j‘ }}</li> {% else %} <li class="green">{{ book.btitle }}---{{ book.bpub_date|date:‘Y年-m月-j日‘ }}</li> {% endif %}
带参数的用法
{% if book.id|mod:3 %} <li class="red">{{ book.btitle }}---{{ book.bpub_date|date:‘Y-m-j‘ }}</li> {% else %} <li class="green">{{ book.btitle }}---{{ book.bpub_date|date:‘Y年-m月-j日‘ }}</li> {% endif %}
注释
在模板中使用如下模板注释,这段代码不会被编译,不会输出到客户端;html注释只能注释html内容,不能注释模板语言。
单行注释:
{# 注释内容 #}
多行注释:
{% comment %} 注释内容 {% endcomment %}
模板继承
概述:
模板继承和类的继承含义是一样的,主要是为了提高代码重用,减轻开发人员的工作量。典型应用:网站的头部、尾部信息。
在父模板里可以定义块,使用标签:
{% block 块名 %} 块中间可以写内容,也可以不写 {% endblock 块名%}
子模板去继承父模板之后,可以重写父模板中的某一块的内容。
继承格式:
{% extends 父模板文件路径%} {% block 块名 %} {{ block.super}} #获取父模板中块的默认内容
重写的内容
{% endblock 块名%}
示例父模板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>base</title> </head> <body> <h1>标题</h1> {% block b1 %} <p>base的信息---b1</p> {% endblock b1 %} {% block b2 %} <p>base的信息---b2</p> {% endblock b2 %} <h1>导航</h1> </body> </html>
示例子模板
{% extends ‘booktest/base.html‘ %} {% block b1 %} {{ block.super }} <h2>子模板--b1</h2> {% endblock b1 %} {% block b2 %} {{ block.super }} <h2>子模板--b2</h2> {% endblock %}
总结:把不同的内容写在块里面,相同的的内容写在块的外面,相同的内容会被子模板继承
Ajax
在不全部加载某一个页面部的情况下,对页面进行局的刷新
HTML中ajax案例
GET方式:
{# username,password为用户提交的表单中的数据 #}
$.get(‘/login_ajax_check/?username=‘+username+"&password="+password, function (data) { if(data.res == ‘ok‘){
{# data为视图传过来的参数 #} location.href = http://www.mamicode.com/‘/success/‘
{# location.href让浏览器访问success页面 #} } lse{ $(‘#errinfo‘).html(‘用户名或密码错误‘).show() } })
POST方式:
{# username,password为用户提交的表单中的数据 #}
$.post(‘/login_ajax_check/‘,{‘username‘:username, ‘password‘: password}, function (data) { alert(data.res) })
CSRF
CSRF全拼为Cross Site Request Forgery,译为跨站请求伪造。CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。
跨站请求伪造产生原因:
1个浏览器访问2个不同的网站A,B
2.浏览器登录A网站成功后会将登录的状态信息session保存到浏览器下一次访问的时候直接就显示登录成功的网页,不需要登录原因是浏览器会把保存的session状态信息带过去验证,通过后不必显示登录页面
3.现在用同一个浏览器访问B网站,紧接着将数据提交到A网站上,此时因为用的是同一个浏览器,会将之前产生的session数据一同提交到A网站上,此时还会把之前保存的session信息提交到A的网站上,同过验证,就产生了跨站请求伪造的情况
解决方法:
- 重要信息如金额、积分等,采用POST方式传递
- 启用CSRF中间件,默认启用《在项目的配置文件中设置》
- ‘django.middleware.csrf.CsrfViewMiddleware‘, CSRF中间件配置--默认开启
- 在form表单中加入标签csrf_token《{% csrf_token %}》
说明:
当启用中间件并加入标签csrf_token后,会向客户端浏览器中写入一条Cookie信息,这条信息的值与隐藏域控制的value属性是一致的,提交到服务器后会先由csrf中间件进行验证,如果对比失败则返回403页面,而不会进行后续的处理。
反向解析
问题产生:
随着功能的增加会出现更多的视图,可能之前配置的正则表达式不够准确,于是就要修改正同表达式,但是正则表达式一旦修改了,之前所有对应的超链接都要修改,真是一件麻烦的事情,而且可能还会漏掉一些超链接忘记修改,有办法让链接根据正则表达式动态生成吗?
答:反向解析。
说明:反向解析会根据应用当中的url匹配的改变,而改变对应html提交的url。。
使用流程:
不带参数的反向解析
1.在项目的url.py文件当中写入
url(r‘^‘, include(‘booktest.urls‘, namespace="booktest"))
2.在应用的url当中写入
url(r‘^fan6/$‘, views.fan1, name=‘fan2‘),
3.在对应的html文件当中写入:
<a href="http://www.mamicode.com/{% url ‘booktest:fan2‘ %}">反向解析</a>
位置参数的反向解析
2.在应用的url当中写入
url(r‘^delete_(\d+)_(\d+)/$‘, views.reverse_url_need_args, name=‘delete‘), #带参数的反向解析
3.在对应的html文件当中写入:
<a href="http://www.mamicode.com/{% url ‘booktest:delete‘ 3 4 %}">带参数的反向解析</a><br>
关键字参数的反向解析
2.在应用的url当中写入
url(r‘^delete_(?P<p1>\d+)_(?P<p2>\d+)/$‘, views.reverse_url_need_args, name=‘delete2‘), #带关键字参数的反向解析
3.在对应的html文件当中写入:
<a href="http://www.mamicode.com/{% url ‘booktest:delete2‘ p1=33 p2=44 %}">关键字参数的反向解析</a>
重定向的时候使用反向解析
导入:from django.core.urlresolvers import reverse
不带参数
return redirect(reverse(‘booktest:fan2‘))
位置参数
return redirect(reverse(‘booktest:delete‘, args=(33, 44)))
关键字参数
return redirect(reverse(‘booktest:delete2‘, kwargs={‘p1‘: 22, ‘p2‘: 33}))
Django中模板总结[模板语言,模板继承,CSRF攻击,反向解析]