Templates
模板
模板的功能:产⽣html,控制页⾯上展⽰的内容。模板⽂件不仅仅是⼀个html⽂件。模板⽂件包含两部分内容:1.静态内容:css,js,html
2.动态内容:⽤于动态去产⽣⼀些⽹页内容,通过模板语⾔来产⽣
1、模板⽂件的使⽤:通常是在视图函数中使⽤模板产⽣html内容返回给客户端
1.加载模板⽂件 loader.get_template(模板⽂件路径)-->获取模板⽂件的内容,产⽣⼀个模板对象2.定义模板上下⽂ ResponseContext-->给模板⽂件传递数据
3.模板渲染产⽣html页⾯内容 render-->⽤传递的数据替换相应的变量,产⽣⼀个替换后的表中html内容 render⾥⾯已经封装了上⾯这些步骤
render和redirect的返回值是HttpResponse的对象,本⾝是函数
创建django项⽬-->创建app-->配置settings app、模板配置、配置mysql数据库、init导⼊pymysql-->创建templates⽂件夹-->定义views-->配置url
模板⽂件加载过程
先去配置的模板⽬录下查找(BASE_DIR);去INSTALLED_APPS下⾯的每个应⽤去找模板⽂件,前提是应⽤中必须有templates⽂件夹
2、模板语⾔:DTL,Django Template Language
模板变量:模板变量名是由数字,字母,下划线和点组成的,不能以下划线开头使⽤模板变量:{{模板变量名}}模板变量的解析顺序:例如:{{book.btitle}}
1.⾸先把book当成⼀个字典,把btitle当成键名,进⾏取值book['btitle']2.把book当成⼀个对象,把btitle当成属性,进⾏取值book.btitle3.把book当成⼀个对象,把btitle当成对象的⽅法,进⾏取值book.btitle例如:{{book.0}}
1.⾸先把book当成⼀个字典,把0当成键名,进⾏取值book['0']2.把book当成⼀个列表,把0当成下标,进⾏取值book[0]如果解析失败,则产⽣内容时⽤空字符串填充模板变量使⽤模板变量时,前⾯的可能是字典、对象、列表 模板标签{%代码段%}for循环:{%for x in 列表%}
#列表不为空时执⾏{% empty %}#列表为空时执⾏{% endfor %}
可以通过{{ forloop.counter}}得到for循环遍历到了第⼏次{% if 条件 %}{% elif 条件 %}{% else %}{% endif %}
关系⽐较操作符: > < >= <= == !=
注意:进⾏⽐较操作时,⽐较操作符两边必须有空格逻辑运算:not and or
过滤器:过滤器⽤于对模板变量进⾏操作
date:改变⽇期的显⽰格式 date|date:'Y年-m⽉-d⽇'length:求长度,字符串、列表 {{value|length}}
default:设置模板变量的默认值 {{value|default:'ha'}}前⾯判断为假使⽤后⾯变量格式:模板变量 | 过滤器:参数
⾃定义过滤器:只能有⼀个参数或者两个参数,⼀个参数时候不⽤传参数,两个参数时需要传⼀个参数在templatetags(在⽬录下新建的⼀个包)中定义#过滤器本质就是python函数from django.template import Library#创建⼀个Library类的对象register=Library()@register.filterdef mod(num): return num%2 == 0-->{%load ⽂件名字%} {if book.id|mod}
{% load filters%} #使⽤
模板注释
单⾏注释:{# 注释内容 #}多⾏注释:{% comment %} 注释内容 {% endcomment %}
模板继承
在⽗模板⾥可以定义块,使⽤标签:{% block 块名 %}
块中间可以写内容,也可以不写 {% endblock 块名 %}
⼦模板去继承⽗模板之后,可以重写⽗模板中的某⼀块的内容继承格式:{% extends ⽗模板⽂件路径 %}{% block 块名 %}
{{ block.super }}#获取⽗模板中块的默认内容重写的内容
{% endblock 块名 %}
{% block title %}{% endblock title %}
把所有页⾯相同的内容放到⽗模板⽂件中,不需要放在块中。有些位置页⾯内容不同,需要在⽗模板中预留块。 html转义
在模板上下⽂中的html标记默认是会被转义的⼩于号< 转换为<⼤于号> 转换为>单引号' 转换为'双引号\" 转换为"与符号& 转换为&
要关闭模板上下⽂字符串的转义:可以使⽤{{模板变量|safe}}也可以使⽤:
{% autoscape off %}模板语⾔代码{% endautoescape %}
模板硬编码中的字符串默认不会经过转义,如果需要转义,那需要⼿动进⾏转义硬编码:{{test|default:'
Hello
'}}
⼿动进⾏转义 {{test|default:<h1>Hello</h1>}}
登录装饰器
在进⾏⽹站开发的时候,有些页⾯是⽤户登陆之后才能访问的,假如⽤户访问了这个地址,需要进⾏登录的判断,如果⽤户登录的话,可以进⾏后续的操作,如果没有登录,跳转到登录页
有些页⾯访问时要先判断是否登录
def login_required(view_func): '''登录判断装饰器'''
def wrapper(request, *view_args, **view_kwargs): # 判断⽤户是否登录
if request.session.has_key('islogin'): #⽤户已登录,调⽤对应的视图
return view_func(request, *view_args, **view_kwargs) else:
#⽤户未登录,跳转到登录页 return redirect('/login') return wrapper
3、csrf攻击
⾸先做⼀个登录页,让⽤户输⼊⽤户名和密码进⾏登录,登录成功之后跳转到修改密码页⾯。在修改页⾯编辑内容,点击确认按钮完成密码修改。登录页需要⼀个模板⽂件login.html,修改密码页⾯也需要⼀个模板⽂件change_pwd.html。显⽰登录页的视图login,验证登录的视图login_check,显⽰发帖页的视图change_pwd,处理修改密码的视图change_pwd_action
1.登陆正常⽹站之后,浏览器保存的sessionid,没有退出
2.不⼩⼼访问了另外⼀个⽹站,并且点击了页⾯上的按钮,这个按钮点了之后是访问之前的⽹站,并且这个按钮中隐藏了其他提交信息
django默认启⽤了csrf保护,只针对post提交表单post提交数据时加上{% csrf_token %}标签
MIDDLEWARE_CLASSES=(......
'django.middleware.csrf.CsrfViewMiddleware',......)
原理:在表单⾥⾯加上{%csrf_token%}
防御原理:
1.渲染模板⽂件时在页⾯⽣成⼀个名字叫做csrfmiddlewaretoken的隐藏域 这个隐藏域由{%csrf_token%}⽣成2.服务器交给浏览器保存⼀个名字为csrftoken的cookie信息
3.提交表单时,两个值都会发给服务器,服务器进⾏⽐对,如果⼀样,则csrf验证通过,否则失败第三⽅⽹站虽然把2中的cookie发过去了,但并没有隐藏域。
4、验证码
在⽤户注册、登录页⾯,为了防⽌暴⼒请求,可以加⼊验证码功能,如果验证码错误,则不需要继续处理,可以减轻业务服务器、数据库服务器的压⼒。
存到session? Redis?
后台⽣成-->发给html显⽰-->提交表单-->后台取数据-->验证
5、反向解析⽐如返回⾸页按钮
当某⼀个url配置的地址发⽣变化时,页⾯上使⽤反向解析⽣成地址的位置不需要发⽣变化作⽤:根据url正则表达式的配置动态的⽣成url
使⽤:在项⽬urls中包含具体应⽤的urls⽂件时指定namespace 再应⽤的urls中配置指定的nameurlpatterns={
url(r'^admin/', include(admin.site.urls)),
url(r'^', include('booktest.urls', namespace='booktest'))}
在应⽤的urls中配置时指定name:urlpatterns={
url(r'', views.index, name='index')}
#urls.py
urlpatterns = [
url(r'^show_args/(\\d+)(\\d+)$', views.show_args, name='show_args'), #捕获位置参数
url(r'^show_kwargs/(?P\\d+)(?P\\d+)$', views.show_kwargs, name='show_kwargs'), #捕获关键字参数]#views.py
def show_args(request): pass
def show_kwargs(request, c, d): return HttpResponse(c+\":\"+d)
#视图中使⽤反向解析
from django.core.urlresolvers import reversedef test_redirect(request):
#url = reverse('booktese:index')
#url = reverse('booktest:show_args', args=(1, 2))
url = reverse('booktest:show_kwargs', kwargs={'c':3, 'd':4}) return redirect(url)