模板介绍
模板致力于表达外观,而不是程序逻辑;设计实现了业务逻辑view 与显示内容template的解耦模板包含两部分
静态:包含html、css、js动态:就是模板语言(简写DTL,定义在django.template)
# 模板处理
1.加载: 根据给定的路径找到模板文件,编译后放在内存中
2.渲染: 使用上下文数据对模板传值并返回动态生成的网页
模板配置:
'DIRS': [os.path.
join(BASE_DIR,
'templates')]
模板语言
作用:获取、处理传入到模板中的上下文数据,动态的产生页面内容包含4种类型:1.变量, 2.标签 , 3.过滤器(可自定义), 4.注释
作用:计算并输出上下文传入的数据.
语法:{{变量}}
变量名规则:由字母、数字、下划线和点组成(不能以下划线开头).
1.字典book[
'name']
2.先属性后方法,将book当作对象,查找属性name,如果没有再查找方法那么()
3.如果是格式为book.0则解析为列表book[
0]
如果变量不存在则插入空字符串
"".
在模板中调用方法时不能传递参数(使用带参数方法,需要使用过滤器)
语法:{% 代码段 %}
-
for循环标签
{%
for item
in 列表 %} 执行循环逻辑
{{ forloop.counter }}获取当前是第几次循环,
从
1开始 {% empty %} 列表为空或不存在时执行此逻辑
{% endfor %}
-
if标签
{%
if ... %}
逻辑
1
{% elif
... %}
逻辑
2
{%
else %}
逻辑
3
{% endif %}
- 比较运算符标签 ,左右两侧必须有空格
==, !=, <, >, <= , >=
- 布尔运算符标签
and, or, not
作用:模板语言中不允许带参数的函数,如果要对变量进行处理,就需要使用过滤器
使用管道符号 | 来应用过滤器,用于进行计算、转换操作,可以使用在变量、标签中
一个参数时:变量|过滤器
两个参数时:变量|过滤器:参数
length: 返回字符串、列表、元组、字典的元素个数(变量 | length)
default: 如果变量不存在时则返回默认值(变量 | default: 默认值)
date: 用于对日期类型的值进行字符串格式化
- Y表示年,格式为
4位,y表示两位的年
- m表示月,格式为
01,
02,
12等
- j表示日,格式为
1,
2等
- H表示时,
24进制,表示
12进制的是时
- i表示分,为
0-
59
- s表示秒, 为
0-
59
日期 | date:
'Y年m月j日 H时i分s秒'
* 当内建过滤器无法满足需求时,需要自定义过滤器
* 过滤器就是python中的函数,注册后就可以在模板中当做过滤器使用
* 自定义过滤器的python包,必须命名为templatetags
* 创建注册对象,必须命名为register
* 在模板中使用模板注释,注释掉某一段代码,那么这段代码不会被编译,不会输出到客户端;注释可以包含任何模板代码,有效的或者无效的都可以注释掉
- html注释只能注释html内容,不能注释模板语言
单行注释
{
多行注释使用comment标签
{% comment %}
...
{% endcomment %}
模板继承
作用:主要是为了提高代码重用,减轻开发人员的工作量典型应用: 网站的头部、尾部信息
# 父模板
-
如果发现一段代码在多个模板中出现,那就应该把这段代码内容定义到父模板中
-
父模板中也可以使用上下文中传递过来的数据
-
父模板定义在templates文件目录
-
block标签: 用于在父模板中预留区域,留给子模板填充差异性的内容
-
可以给预留区域定义名字,但多个预留区域名字布恩那个相同
-
为了更好的可读性,建议给endblock标签写上名字,这个名字与对应的block标签名字相同
{% block 名称 %}
预留区域,可以编写默认内容,也可以没有默认内容
{% endblock 名称 %}
# 子模板
-
子模板定义在templates/应用 文件目录下
-
extends标签:继承,写在子模板文件的第一行
-
子模板不用填充父模板中的所有预留区域,如果子模板没有填充,则使用父模板定义的默认值
{% block 名称 %}
实际填充内容
{{block.super}} 用于获取父模板中block的内容,也可以不获取
{% endblock 名称 %}
# 注意点:
1.子模板继承父模板之后,本身原有的内容是不起作用的
2.父模板不能把上下文传给子模板,只能继承内容不继承上下文
HTML转义
在视图中,通过调用模板传递上下文,模板对上下文传递的字符串进行输出时,会对以下字符自动转义作用:转义后标记代码(标签)不会被直接解释执行,而是被直接呈现,防止客户端通过嵌入js代码攻击网站
小于号 < 转换为 <
大于号 > 转换为 >
单引号 ' 转换为 &
#39;
双引号
" 转换为 "
与符号 & 转换为 &
禁止HTML转义
过滤器escape:可以实现对变量的HTML转义,默认模板就会转义,一般省略;{{变量 | escape}}过滤器safe : 禁用转义,告诉模板这个变量是安全的,可以解释执行;{{变量 | safe}} 标签autoescape : 设置一段代码都禁用转义,接受on(启用转义)、 off(禁用转义)参数其他 1.对于在模板中硬编码<, >, ‘, “, &不会被转义 2.在模板中硬编码如果希望出现转义的效果,则需要手动编码转义
CSRF
CSRF全拼为Cross Site Request Forgery, 译为跨站请求伪造CSRF 指攻击者盗用了你的身份,以你的名义发送恶意请求;造成个人隐私泄漏以及财产安全
1.Django 第一次响应来自某个客户端的请求时,会在服务器端随机生成一个
token,把这个
token 放在 cookie 里。然后每次 POST 请求都会带上这个
token,这样就能避免被 CSRF 攻击
2.在返回的 HTTP 响应的 cookie 里,django 会为你添加一个 csrftoken 字段,其值为一个自动生成的
token
3.在所有的 POST 表单时,必须包含一个 csrfmiddlewaretoken 字段 (只需要在模板里加一个 csrf_token标签, django 就会自动帮我们生成)
4.在处理 POST 请求之前,django 会验证这个请求的 cookie 里的 csrftoken 字段的值和提 交的表单里的 csrfmiddlewaretoken 字段的值是否一样。如果一样,则表明这是一个合法的请求,否则,这个请求可能是来自于别人的 csrf 攻击,返回
403 Forbidden.
验证码
在用户注册、登录页面,为了防止暴力请求,可以加入验证码功能,如果验证码错误,则不需要继续处理,可以减轻业务服务器、数据库服务器的压力
反向解析
根据正则应用:模板中的超链接,视图中的重定向
url = (r
'^',
include(
'Book.urls', namespace=
'book')),
url = (r
'^fan123/$', fan1, name=
'fan1'),
url(r
'^fan123/(\d+)/(\d+)/$', fan2, name=
'fan2')
url(r
'^fan123/(?P<num1>\d+)/(?P<num2>\d+)/$', fan3, name=
'fan3')
<
a href=
'{% url "book:fan1" %}}'></
a>
<
a href=
'{% url "book:fan2" 18 188 %}'></
a>
<
a href=
'{% url "book:fan3" num1=18 num2=188 %}'></
a>
<
a href=
'{% url "book:fan3" 18 188 %}'></
a>
from django.core.urlresolvers import reverse
return redirect(reverse(
'book:fan1'))
return redirect(reverse(
'book:fan2', args=(
18,
188)))
return redirect(reverse(
'book:fan3', args=(
18,
188)))
return redirect(reverse(
'book:fan3',kwargs=(
'num1':
18,
'num2':
188)))
配置流程
# 创建项目
django-admin startproject 项目名称
# 创建应用
cd BookManager/
python manage.py startapp 应用名称
#修改解释器路径
/home/python/.virtualenvs/py3_django/bin/python
# 运行服务器
python manage.py runserver
# 生成、执行迁移
python manage.py makemigrations
python manage.py migrate
# 界面本地化
LANGUAGE_COOE=
"zh-Hans"
TIME_ZONE=
"Asia/Shanghai"
# 创建管理员
python manage.py createsuperuser
# 配置URL
## 项目
url(r
'^', include(
'Book.urls')),
## 应用
url(r
'^booklist/$', bookList),
# 配置mysql数据库
## __init__下
import pymysql
pymysql.install_as_MySQLdb()
## settings下
DATABASES = {
'default': {
'ENGINE':
'django.db.backends.mysql',
'NAME':
'Bookdb',
'HOST':
'192.168.80.132',
'PORT':
'3306',
'USER':
'root',
'PASSWORD':
'mysql',
}
}
# 创建模板文件夹templates,设置模板路径
"DIRS":[os.path.join(BASE_DIR,
"templates")]
# 创建静态文件夹static,设置文件路径
STATICFILES_DIRS = [
os.path.join(BASE_DIR,
'static'),
]
# 上传文件,在static下创建media,其下再创建Book
## 在settings配置文件上传时保存到的路径
MEDIA_ROOT=os.path.join(BASE_DIR,
'static/media')
# 错误视图配置(线上模式)
DEBUG = False
ALLOWED_HISTS = [
'*']
# 配置自定义过滤器
## 在应用下新建templatetags(必须此名)包,在包下新建py文件定义过滤器函数,注册对象必须命名为register
## 加载过滤器{load py文件名}
# 定义父子模板
## 父模板定义在templates文件目录下
##子模板定义在templates/应用文件目录下
## 子模板中使用{% extends '父模板名' %}
# 自定义中间件
在应用中新建middleware.py文件,在文件中定义类TestMiddleware
在settings.py下配置中间件
MIDDLEWARE_CLASSES= [
# 注册自定义中间件
'Book.middleware.TestMiddleware',
]
# 站点管理中重写模板
在templates 目录下创建 admin目录
再在admin文件下创建base_site.html
{% extends
"admin/base.html" %}
{% block title %}{{ title }} | {{ site_title|
default:_(
'Django site admin') }}{% endblock %}
{% block branding %}
{#<h1 id=
"site-name"><a href=
"{% url 'admin:index' %}">{{ site_header|
default:_(
'Django administration') }}</a></h1>#}
{# 自定义内容 #}
<h1 id=
"site-name"><a href=
"{% url 'admin:index' %}">电商项目</a></h1>
{% endblock %}
{% block nav-global %}{% endblock %}