# 模板引擎
### 蓝本使用
- 说明:
当大量视图函数放在一个文件中,很明显是不合适的。最好的时解决方案是根据需要将相关的视图函数放在单独的文件中。蓝本就是为了解决这个问题而出现的。
- 使用:
```python
# 导入蓝本
from flask import Blueprint
# 创建对象,可以统一指定路由前缀
user = Blueprint('user', __name__, url_prefix='/user')
# 添加视图函数
@user.route('/login/')
def login():
return '欢迎登录'
@user.route('/register/')
def register():
return '欢迎注册'
# 注册蓝本(蓝本不注册不能使用),也可以指定路由前缀(优先级更高)
from user import user
app.register_blueprint(user, url_prefix='/u')
```
### cookie
- 说明:
因为HTTP协议是无状态无连接的,因此当用户在一个网站做连续操作,每次都需要提供用户身份信息;为了简化这种操作,我们可以通过cookie携带特定的信息。当第一次访问网站时设置,以后每次访问都携带。
- 使用:
```python
from flask import Blueprint, request, make_response
cookie = Blueprint('cookie', __name__)
# 获取cookie
@cookie.route('/get/')
def get_cookie():
return request.cookies.get('name', '你是哪个二哥?')
# 设置cookie
@cookie.route('/set/')
def set_cookie():
resp = make_response('cookie已设置')
# 设置cookie,默认有效期为浏览器关闭
# max_age:有效期,是一个整数,推荐使用
# expires:有效期,是一个datetime类型数据
resp.set_cookie('name', '二狗子', max_age=10)
return resp
# 删除cookie
@cookie.route('/del/')
def del_cookie():
resp = make_response('cookie已删除')
# 删除cookie,其实是设置cookie立即失效
resp.delete_cookie('name')
return resp
```
### session
- 说明:
session是比cookie更加安全的一种携带有效信息的方式,功能与cookie相同。
- 分类:
- server side session:数据存在服务器上,客户端保存的是session_id(通过cookie传输)
- client side session:将session数据加密,编码,然后存放在客户端,flask默认采用这样方式
- 使用:
```python
from flask import Blueprint, session
sess = Blueprint('session', __name__)
# 获取session
@sess.route('/get/')
def get_session():
return session.get('name', 'who are you?')
# 设置session
@sess.route('/set/')
def set_session():
# 设置永久有效,默认浏览器关闭即失效
# 设置为True时,有效才有意义,
# 有效期由配置选项PERMANENT_SESSION_LIFETIME指定
# 默认有效期是31天
session.permanent = True
session['name'] = 'wangdahua'
return 'session已设置'
# 删除session
@sess.route('/del/')
def del_session():
# 删除指定session,第二参数设置None,删除不存在的session也不报错
# session.pop('name', None)
# 清空所有session
session.clear()
return 'session已删除'
```
### flask-session
- 说明:
是将session数据保存到服务器的解决方案。
- 安装:`pip install flask-session`
- 使用:将session存储到redis中
```python
from flask import Flask, session
from flask_script import Manager
from flask_session import Session
from redis import Redis
app = Flask(name)
# 配置
# 是否拥有生效,设置为True之后,有效期由下面选项决定
app.config['SESSION_PERMANENT'] = True
# 默认31天,可以是timedelta或int的数据
app.config['PERMANENT_SESSION_LIFETIME'] = 10
# 指定session的保存方式
app.config['SESSION_TYPE'] = 'redis'
# 指定redis连接实例,默认127.0.0.1,6379端口,0数据库
app.config['SESSION_REDIS'] = Redis()
manager = Manager(app)
sess = Session(app)
@app.route('/')
def index():
return 'flask-session'
@app.route('/get/')
def get_session():
return session.get('name', 'who are you?')
@app.route('/set/')
def set_session():
session['name'] = 'ergou'
return 'session已设置'
if __name__ == '__main__':
manager.run()
```
### 模板引擎
- 说明:
模板文件就是按照特定规则书写的负责展示效果的HTML文件;模板引擎就是提供特定替换和解析的工具。
- Jinja2:
在flask中使用的是Jinja2模板引擎,它是由flask核心开发人员开发的。
###Jinja2语法
- 目录结构
```
project/
manage.py # 启动控制代码
templates/ # 模板文件目录
```
- 模板渲染
- 在`templates`目录下创建一个模板文件`index.html`
- 在视图函数中渲染模板`render_tempate('index.html')`
- 设置模板文件自动加载`app.config['TEMPLATES_AUTO_RELOAD'] = True`
- 渲染模板字符串`render_template_string('<h1>Hello World!</h1>')`
- 使用变量
- 需要将解析的变量放在`{{ }}`中
- 在渲染模板时需要将解析的变量分配过去,特殊的除外(g)
- 注释写在`{# #}`中
- 渲染模板字符串的方式与渲染模板文件相同
- 使用过滤器
- 说明:过滤器就是对要解析的变量进行特定的处理后,然后在输出。
- 使用:`{{ name | upper }}`,转换为全大写输出
- 常用过滤器:
| 过滤器 | 说明 |
| ---------- | ----------------- |
| upper | 全大写 |
| lower | 全小写 |
| title | 每个单词首字母大写 |
| capitalize | 首字母大写 |
| trim | 去掉两边的空白 |
| striptags | 过滤掉HTML标签 |
| safe | 渲染时不转义(默认会转义所有内容) |
- 在模板文件中,动态开启关闭转义
```html
{% autoescape False %}
<div>Hello {{ name }}</div>
{% endautoescape %}
```
- 流程控制
```html
{% if name %}
<h1>Hello {{ name }}</h1>
{% else %}
<h1>Hello World!</h1>
{% endif %}
<ol>
{% for i in range(10) %}
<li>{{ i }}</li>
{% endfor %}
</ol>
```
- 文件包含
- 说明:可以避免大量的重复书写,包含相当于将被包含的内容粘贴过来。
- 使用:`{% include 'include2.html' %}`
- 宏的使用
- 定义宏:`{% macro 宏名(参数) %}宏内容{% endmacro %}`
- 调用宏:`{{ 宏名(参数) }}`
- 导入宏:`{% from '宏所在文件' import 宏名 %}`
- 说明:宏采用了类似于python中的函数进行定义和调用,可以减少代码的重复书写。
- 模板继承
- 说明:一个网站的多个页面,具有相同的结构,只有少许的差别,可以通过继承减少重复书写。
- 使用:
- 需要先定义一个基础模板,专门用来被其他模板继承的,将其中可能需要修改的地方使用block起名
- 子模板继承基础模板需要使用:`{% extends '基础模板' %}`
- 在子模板中可以根据block名字对父级模板中的内容进行修改、删除等操作
- 若想保留父父模板中的内容,可以通过:`{{ super() }}`
### 练习:
- 自己定义一个基础模板,可以使用bootstrap样式,让其他模板继承
- 自己学习flask-bootstrap扩展的使用,然后定制基础模板