请求的钩子函数
# -*- coding:gbk -*-
from flask import Flask,request
app = Flask(__name__)
@app.route('/',methods=['GET','POST'])
def index():
print('DDOS')
return 'index'
@app.before_first_request
def before_first_request():
print('before_first_request')
@app.before_request
def before_request():
print('before_request')
# return u'哈哈'
@app.after_request
def after_request(response):
print('after_request')
return response
@app.teardown_request
def teardown_request(e):
print('teardown_request%s')%e
if __name__ == '__main__':
app.run(debug=True)
----------------
返回结果:
before_first_request
before_request
DDOS
after_request
teardown_requestNone
第二次访问结果:
before_request
DDOS
after_request
teardown_requestNone
打开before_request函数的‘哈哈’注释运行,直接跳过index函数,运行结果:
before_first_request
before_request
after_request
teardown_requestNone
浏览器中显示:哈哈
保持状态
创建cookie
from flask import Flask,make_response
@app.route('/set_cookie',methods=['GET','POST'])
def set_cookie():
response = make_response('this is a cookie')
response.set_cookie('name','wxx',3600)#3600为过期时间
response.headers["Set-Cookie"] = "name1=naxyl; Expires=Tue, 28-Nov-2017 08:19:03 GMT; Max-Age=3600; Path=/set_cookie"
return response
-----
ps:
naxyl='南安小淫龙'
获取cookie
from flask import Flask,request
@app.route('/get_cookie',methods=['GET','POST'])
def get_cookie():
name = request.cookies['name']
return name
删除cookie
from flask import Flask,make_response
@app.route("/delete_cookie")
def delete_cookie():
response = make_response("delete success")
# 删除cookie,实质上是设置cookie的过期时间和创建时间一样,不是物理删除
response.delete_cookie("name")
return response
创建session
from flask import Flask,session
# app.config["SECRET_KEY"] = "asdfjksadjfa"
app.secret_key = "C37hpKSbH0LSCNVyZWk9CQieQeJVPv5/0IYyuvnIPgI3Uzq+70T2BV5G9vP1fvx4"#两者都可以
@app.route('/set_session',methods=['GET','POST'])
def set_session():
session['age']=12
return 'OK'
#session存储在redis中
#session在浏览器中是依托于cookie的,假如用户设置禁止接收cookie时,可以存在url地址当中
获取session
from flask import Flask ,session
@app.route('/get_session',methods=['GET','POST'])
def get_session():
age = session.get('age')
return "%d"%age
请求上下文
上下文:相当于一个容器,保存了Flask程序运行过程中的一些信息。
1、请求上下文
request:封装了HTTP请求的内容,针对的是http请求。举例:user = request.args.get(‘user’),获取的是get请求的参数。
session:用来记录请求会话中的信息,针对的是用户信息。举例:session[‘name’] = user.id,可以记录用户信息。还可以通过session.get(‘name’)获取用户信息。
2、应用上下文
current_app:可以通过current_app.name打印当前app的名称,也可以在current_app中存储一些变量,例如:
应用的启动脚本是哪个文件,启动时指定了哪些参数
加载了哪些配置文件,导入了哪些配置
连了哪个数据库
有哪些public的工具类、常量
应用跑再哪个机器上,IP多少,内存多大
current_app.name
current_app.test_value=’value’
g变量:
g作为flask程序全局的一个临时变量,充当者中间媒介的作用,我们可以通过它传递一些数据,g保存的是当前请求的全局变量,不同的请求会有不同的全局变量,通过不同的thread id区别
g.name=’abc’
两者区别:
请求上下文:保存了客户端和服务器交互的数据
应用上下文:flask 应用程序运行过程中,保存的一些配置信息,比如程序名、数据库连接、应用信息等
flask_script
用来数据库迁移工作
# -*- coding:gbk -*-
from flask import Flask
from flask_script import Manager
app = Flask(__name__)
manager = Manager(app)
@app.route('/',methods=['GET','POST'])
def index():
return '123'
if __name__ == '__main__':
# app.run()
manager.run()
---------
在终端运行
python 文件名.py runserver
-?, --help show this help message and exit
-h HOST, --host HOST
-p PORT, --port PORT
--threaded
--processes PROCESSES
--passthrough-errors
-d, --debug enable the Werkzeug debugger (DO NOT use in production
code)
-D, --no-debug disable the Werkzeug debugger
Jinja2渲染模板
from flask import Flask,render_template
def render_templates():
my_list=[1,1,2,3,4,5,6]
return render_template('index.html',my_list=my_list)
----------------------------------------------------------
模板中:
{{ my_list }}
{{ my_list[0] }}#取第0位的元素
{{ my_list.1 }}#取第1为的元素
解包
@app.route('/')
def render_templates():
my_list=[1,2,3,4,5,6]
my_dict = {
'my_list':my_list,
'name':'wxx',
'age':23
}
return render_template('index.html',**my_dict)
-----------------------------------------
模板中:
{{ my_list }} [1, 2, 3, 4, 5, 6]
{{ name }} wxx
{{ age }} 23
注释
<!--{{ my_int }}<br/>--> 查看源代码时能看见
{#{{ my_int }}<br/>#} 查看源代码时不能看见
字符串操作
safe:禁用转义
<p>{{ '<em>hello</em>' | safe }}</p>
capitalize:把变量值的首字母转成大写,其余字母转小写
<p>{{ 'hello' | capitalize }}</p>
lower:把值转成小写
<p>{{ 'HELLO' | lower }}</p>
upper:把值转成大写
<p>{{ 'hello' | upper }}</p>
title:把值中的每个单词的首字母都转成大写
<p>{{ 'hello' | title }}</p>
reverse:字符串反转
<p>{{ 'olleh' | reverse }}</p>
format:格式化输出
<p>{{ '%s is %d' | format('name',17) }}</p>
striptags:渲染之前把值中所有的HTML标签都删掉
<p>{{ '<em>hello</em>' | striptags }}</p>
truncate: 字符串截断
<p>{{ 'hello every one' | truncate(9)}}</p>
链式调用:(与Django的不同)
<p>{{ 'olleh' | reverse | upper}}</p>
列表操作
first:取第一个元素
<p>{{ [1,2,3,4,5,6] | first }}</p>
last:取最后一个元素
<p>{{ [1,2,3,4,5,6] | last }}</p>
length:获取列表长度
<p>{{ [1,2,3,4,5,6] | length }}</p>
sum:列表求和
<p>{{ [1,2,3,4,5,6] | sum }}</p>
sort:列表排序
<p>{{ [6,2,3,1,5,4] | sort }}</p>
特殊情况(与Django的不同)
my_dict_list = [
{
"name": "laowang",
"age": 28
},
{
"name": "xiaohua",
"age": 18
}
------------------------------------------------------
{{ my_dict_list | sum(attribute="age") }}#特定属性值相加
my_int = 23
-----------------------------------------
{{ my_int + my_int + my_list.2 }}
语句块过滤
{% filter upper %}
一大堆文字
{% endfilter %}
自定义过滤器
假如给定的过滤器不满足我们的需求就需要自定义过滤器
方法一:
@app.template_filter('lsreverse')
def do_ls_reverse(ls):
ls.reverse()
return ls
-----------------------------
#模板中:
<p>{{ my_list | lsreverse }}</p>
方法二:
def do_ls_reverse(ls):
ls.reverse()
return ls
# 方式2:使用app.的add_template_filter方法去添加过滤器
app.add_template_filter(do_ls_reverse, "lsreverse")
---------------------------------------------
模板中:
<p>{{ my_list | lsreverse }}</p>
if语句
{% for foo in my_list %}
{% if foo>3 %}
{{ foo }}
{% else %}
小于等于三
{% endif %}
{% endfor %}
----------------------------------------
{% if 'nijijkji' |length>3 %}
如果字符串长度大于3打印
{% endif %}
循环
{% for post in posts %}
<div>
<h1>{{ post.title }}</h1>
<p>{{ post.text | safe }}</p>
</div>
{% endfor %}
-------------------
#for与if 组合使用
{% for foo in my_list if foo>3 %}
{{ foo }}
{% endif %}
{% endfor %}
在一个 for 循环块中你可以访问这些特殊的变量:
变量 | 描述 |
---|---|
loop.index | 当前循环迭代的次数(从 1 开始) |
loop.index0 | 当前循环迭代的次数(从 0 开始) |
loop.revindex | 到循环结束需要迭代的次数(从 1 开始) |
loop.revindex0 | 到循环结束需要迭代的次数(从 0 开始) |
loop.first | 如果是第一次迭代,为 True 。 |
loop.last | 如果是最后一次迭代,为 True 。 |
loop.length | 序列中的项目数。 |
loop.cycle | 在一串序列间期取值的辅助函数。见下面示例程序。 |
loop.cycle实例
{% for foo in my_list%}
{{loop.cycle('odd','even')}} {{ foo }}<br>
{% endfor %}
---------------
输出:
odd 1
even 2
odd 3
even 4
odd 5
even 6
loop.index实例
{% for foo in my_list%}
{{loop.index}}, {{foo}}
{% endfor %}
-----------------------
1, 1
2, 2
3, 3
4, 4
5, 5
6, 6
去空格标识符
{% for foo in my_list %}
{{foo}}
{% endfor %}
-------------
结果:
1 2 3 4 5 6
'-'为去空格标识符
{% for foo in my_list -%}
{{foo}}
{%- endfor %}
-------------------
结果:
123456
宏
<form>
<label>用户名:</label><input type="text" name="username"><br/>
<label>身份证:</label><input type="text" name="idcard"><br/>
<label>密码:</label><input type="password" name="password"><br/>
<label>确认密码:</label><input type="password" name="password2"><br/>
<input type="submit" value="提交">
</form>
-----------------------------------------------------------
{% macro input(label="",type="text",name="",value="")%} #function 函数名 参数
<label>{{ label }}</label><input type="{{ type }}"
name="{{ name }}"><br/>
#函数表达式
{% endmacro %}
#相当于定义一个函数
<form>
{{ input('用户名',name="username") }}
{{ input('身份证',name="idcard") }}
{{ input('密码','password',name="password") }}
{{ input('确认密码','password',name="password") }}
{{ input(type='submit',value='提交') }}
</form>
#相当于调用一个函数
-------------------------------------------------------
#还可以再生成一个html文件 文件名.html
{% macro input(label="",type="text",name="",value="")%}
<label>{{ label }}</label><input type="{{ type }}"
name="{{ name }}"><br/>
↓
↓
{% import '文件名.html' as func %}
<form>
{{ func.input('用户名',name="username") }}
{{ func.input('身份证',name="idcard") }}
{{ func.input('密码','password',name="password") }}
{{ func.input('确认密码','password',name="password") }}
{{ func.input(type='submit',value='提交') }}
</form>
{% endmacro %}
模板继承
#创建父模板base.html
{% block top %}
顶部
{% endblock top %}
{% block content %}
哈哈
{% endblock content %}
{% block bottom %}
底部
{% endblock bottom %}
--------------------------------------------------
#创建子模板child.html
{% extends 'base.html' %}
{% block content %}
自己不努力可别怪老王不客气
{{ super() }}
{% endblock content %}
include包含
首先创建include.html文件
哈哈
在创建temp_include.html文件
...
{% include 'include.html' ignore missing %}
...
#包含在使用时,如果包含的模板文件不存在时,程序会抛出TemplateNotFound异常,可以加上 ignore missing 关键字。如果包含的模板文件不存在,会忽略这条include语句。
Flask特有的变量和函数
#创建temp5.html文件
...
{{ g.age }}<br>
{{ g.get("age") }}<br>
{{ session['name'] }}<br>
{{ request.url }}<br>
{{ config.root_path }}<br>
<a href="{{ url_for('index') }}" >主页</a>
...
-------------------------------------------------------
from flask import Flask , g,session
app.secret_key = "C37hpKSbH0LSCNVyZWk9CQieQeJVPv5/0IYyuvnIPgI3Uzq+70T2BV5G9vP1fvx4"
@app.route('/demo5')
def demo5():
session['name']='wxx'
g.age='23'
return render_template('temp5.html')
flash
from flask import Flask,flash
import sys
app = Flask(__name__)
reload(sys)
sys.setdefaultencoding("gbk")#或utf-8
@app.route('/demo6')
def demo6():
flash(u'哈')#闪现进消息队列
return 'success'
--------------------------------------------------
模板
{% for message in get_flashed_messages() %}
{{ message }}
{% endfor %}
#get_flashed_message()函数取出它们并全部消费掉