Flask——基础知识
Flask应用程序
一个简单的Flask应用程序
# 导入flask程序 from flask import Flask # 初始化flask对象 app = Flask(__name__) # 装饰器模式,新建路由,绑定index视图函数 @app.route("/index") def index(): return "index page" # 判断当前的__name__ 是否是__main__ # __name__ : 如果做为单一模块运行,表示主模块名称:__main__ # 如果做为模块导入,那么就表示当前模块的名字 if __name__ == '__main__': # 启动app app.run()
运行之后,在浏览器地址栏输入:http://127.0.0.1:5000/index
就可以看到视图函数返回的内容

Flask程序创建的参数
Flask程序创建(app = Flask(初始化参数)的时候其实有很多的参数,前面提到的例子中只写了:__name__。下面会详细说下创建的参数。
源码中的参数是:

这里我只介绍常用的
import_name
# 第⼀一个参数:指定当前应⽤用程序所处于的模块,其可以决定静态⽂文件从哪个位置开始查找, # 在加载静态⽂文件时,会从第⼀一个参数指定的模块下开始查找, # 如果模块不不存在,会从当前app所在模块的⽬目录下开始找'static'⽂文件夹
# 多数人在这个地方传入__name__。所以默认是__main__,因为不存在__main__模块,所以会从当前模块的同级目录查找static文件夹
static_url_path
静态文件访问路径
static_folder
静态文件所处文件夹
template_folder
模板文件所处文件夹
默认是:templates
程序运行时的参数
app.run("运行参数") 运行参数: debug # 表示启用debug模式 host # 运行的地址 port # 绑定的端口
Flask项目加载配置
从对象中加载配置
from flask import Flask app = Flask(__name__) class Config(object): # 开启调试模式 DEBUG = True # 设置debug开启,当出错会在网页中显示出来。 NAME = "name" # 设置一个自定义的变量 # 从对象当中加载 app.config.from_object(Config) @app.route("/") def index(): # a = 1 / 0 print(app.config.get("NAME")) # 读取自定义的变量 return "index page" if __name__ == '__main__': app.run()
从路径中加载配置
首先要在当前目录建一个文件,文件名和后缀可以任意取,但是本着见名知意的原则,我取名为了:config.cfg,在文件中我写入了:DEBUG = True
from flask import Flask app = Flask(__name__) app.config.from_pyfile("config.cfg") @app.route("/") def index(): # a = 1 / 0 return "index page" if __name__ == '__main__': app.run()
其他方法
app.config['DEBUG'] = True app.DEBUG = True app.run(debug = True)
返回状态码、抛出和捕捉异常
返回状态码
编码:
@app.route("/") def index(): return "状态码", 666
效果

自定义相应头
编码:
@app.route("/") def index(): return "状态码", 666, {"name": "zhangshan"}
效果:

抛出异常
编码:
# 导入包 from flask import abort
效果:

捕获异常
编码:
from flask import Flask, abort app = Flask(__name__) @app.errorhandler(404) # 除了404,这些状态码,也可以对指定的错误进行捕获和处理,比如zeroDivisionError def demo2(e): """专⻔门捕获指定的状态码异常信息,然后处理理异常""" print(e) return '服务器器搬家了了' @app.route('/index') def index(): abort(404) if __name__ == '__main__': app.run()
效果:

Flask路由
请求方法
限定请求方法
@app.route(‘/‘, methods=[‘GET’, ‘POST’])
获取请求方法
首先要导入request模块,里面封装着用户请求
from flask import request
然后通过request.method可以获取请求方法。
其他通过request获取的
from flask import Flask from flask import request app = Flask(__name__) @app.route("/index",methods=["GET","POST"]) def index(): # request : 封装的所有的请求信息 # request.form : 提取表单数据 name = request.form.get("name") age = request.form.get("age") # request.args :提取?后面的数据 city = request.args.get("city") # request.data:提取的是原始数据(json) print("request.data = %s" % request.data.decode()) return "name = %s,age = %s,city = %s" % (name, age, city) if __name__ == '__main__': app.run()
默认请求方法
HEAD:获取相应头信息
GET:获取数据,全部信息
OPTIONS:查看某个url可以支持哪些请求方法。
url_map
url_map又可以称为路由视图关系映射,可以通过app.url_map查看。
当同一个路由映射两个视图,当发送请求时,路由会根据map表的顺序从上到下查找,会执行先定义的路由和视图
获取路由的参数
from flask import Flask app = Flask(__name__) @app.route('/index/<id>') def index(id): return "id: %s" % id if __name__ == '__main__': app.run(debug=True)
重定向
首先引入模块:
from flask import redirect
重定向到指定网址
return redirect(‘http://www.baidu.com’))
重定向到指定视图
return redirect(url_for("index")) # url_for需要导包
重定向传参
return redirect(url_for("order", id=11))
from flask import Flask, redirect, url_for app = Flask(__name__) @app.route("/order/<id>") def order(id): return "id:%s" % id @app.route('/') def demo(): return redirect(url_for("order", id=11)) # 相当于重定向到指定视图对应的url,而且路由中必须有和其匹配的,否则会报错 if __name__ == '__main__': app.run()
自定义路由匹配转换器
首先导入模块
from werkzeug.routing import BaseConverter
下面是自带的转换器,Ctrl+鼠标左键点BaseConverter可以看到默认的转换器
DEFAULT_CONVERTERS = { 'default': UnicodeConverter, 'string': UnicodeConverter, 'any': AnyConverter, 'path': PathConverter, 'int': IntegerConverter, 'float': FloatConverter, 'uuid': UUIDConverter, }
实际中我们需要这个转换器帮我们做更多的筛选。所以需要自定义。
例子:
from flask import Flask from werkzeug.routing import BaseConverter class RegexConverter(BaseConverter): """⾃自定义转换器器:实现最多传⼊入5个数字""" # 重写⽗父类的属性,定义转换器规则 regex = '[0-9]{5}' app = Flask(__name__) # 将自定义的转换器添加到转换器列表中 app.url_map.converters['re'] = RegexConverter @app.route('/order/<re:order_id>') def demo1(order_id): return 'demo1 %s' % order_id if __name__ == '__main__': app.run()
上面例子中写的太死,下面是优化了的:
from flask import Flask from werkzeug.routing import BaseConverter class RegexConverter(BaseConverter): def __init__(self, url_map, *args): # 在启动服务器的时候flask就自动的将正则放入了args中了,等浏览器输入会放入url_map中 super(RegexConverter, self).__init__(url_map) self.regex = args[0] app = Flask(__name__) # 将自定义的转换器添加到转换器列表中 app.url_map.converters['re'] = RegexConverter @app.route('/order/<re("[0-9]{5}"):order_id>') def demo1(order_id): return 'demo1 %s' % order_id if __name__ == '__main__': app.run()
返回JSON
json模块
json_dict = { ‘name’:’zxc’, ‘age’:18 } from flask import Flask, json json_str = json.dumps(json_dict)
这个成json后,传浏览器的时候Content-Type还是text/html,还需要再修改,不建议
jsonify模块
json_dict = { ‘name’:’zxc’, ‘age’:18 } from flask import Flask, jsonify json_str = jsonify(json_dict)
这个转json后,浏览器传输的时候Content-Type变成了application/json。建议使用
请求对象属性
data:读取请求体中的原始字符串,比如json字符串
form:用户通过表单发给服务器的数据,比如POST表单数据到服务器
args:用户通过查询参数发给服务器的数据,也就是url中?后面的参数。比如:http://127.0.0.1/upload?name=lisi中的name=lisi
cookies:用户发送给服务器的cookie数据
headers:请求头信息
method:请求方法
url:请求地址
files:用户发送给服务器的文件信息,比如:文件上传时信息
补充:服务器接收用户上传文件:
pic = request.files.get("pic") pic.save("./123.jpg")
请求勾子
使用装饰器实现监听请求和响应过程
@app.before_first_request
说明:在服务器第一次收到请求前调用,可以做一些初始化,而且只会执行一次,比如连接到数据库
@app.before_request
说明:在请求之前执行
@app.after_request
说明:在请求之后执行
@app.teardown_request
说明:”after_request”和”teardown_request”会在请求处理完成后被调用。区别是”after_request”只会在请求正常退出时才会被调用,它必须传入一个参数来接受响应对象,并返回一个响应对象,一般用来统一修改响应的内容。而”teardown_request”在任何情况下都会被调用,它必须传入一个参数来接受异常对象,一般用来统一释放请求所占有的资源。
以上所以的例子:
from flask import Flask, g, request app = Flask(__name__) @app.before_request def before_request(): print 'before request started' print request.url @app.before_request def before_request2(): print 'before request started 2' print request.url g.name="SampleApp" @app.after_request def after_request(response): print 'after request finished' print request.url response.headers['key'] = 'value' return response @app.teardown_request def teardown_request(exception): print 'teardown request' print request.url @app.route('/') def index(): return 'Hello, %s!' % g.name if __name__ == '__main__': app.run(host='0.0.0.0', debug=True)
访问”http://localhost:5000/”后,会在控制台输出:
before request started http://localhost:5000/ before request started 2 http://localhost:5000/ after request finished http://localhost:5000/ teardown request http://localhost:5000/
状态保持
cookie
cookie是通过响应将cookie写入到浏览器的
在flask中,先要设置cookie,首先要“做”一个响应
response = make_response('') # make_response这个包需要导入
设置cookie
response.set_cookie('name','zxc') response.set_cookie('age', '18', max_age=3600)
读取cookie
request.cookies.get('name')
删除cookie
response.delete_cookie('name')
session
导入模块:
from flask import Flask, session
加盐:
app.config['SECRET_KEY'] = 'fasf' # 加盐是让你的原始数据加上这个你随意写入的(一般要用个加密算法得出的结果)的数据再加密,确保数据的安全性
设置session
session['name'] = 'zxc'
读取session
name = session.get(‘name’) name = session['name']
删除session
session.pop('name')
设置session过期时间:
# 过期时间, 通过cookie实现的 from datetime import timedelta session.permanent = True # 默认是31天 app.permanent_session_lifetime = timedelta(minutes=5) # 指定session具体的过期时间
注意:无论是cookie还是sesion都是存储在浏览器的一个文件中作为状态保持的,而实际应用中,是将私密信息放到服务器的。用Flask中封装的flask_session中的Session来处理,这个会在你的本地和服务器都存储,看你怎么取。
Flask_Script
Flask中的脚本扩展工具包,再开发中我们可以用pycharm来运行,但是部署到服务器就没有pycharm来启动了,需要这些脚本工具
使用步骤
导入模块
from flask_script import Manager
创建脚本管理对象
manager = Manager(app)
使用脚本管理器对象启动程序
manager.run()
再终端上执行脚本命令
python demo.py runserver -p 5001 -d # -d是开启调试模式
添加脚本
Flask Script扩展提供向Flask插入外部脚本的功能,包括运行一个开发用的服务器,一个定制的Python shell,设置数据库的脚本,cronjobs,及其他运行在web应用之外的命令行任务;使得脚本和系统分开;
Flask Script和Flask本身的工作方式类似,只需定义和添加从命令行中被Manager实例调用的命令;
Manager只有一个参数——Flask实例,也可以是一个函数或其他的返回Flask实例;
编码
@manager.command def test_custom_script(): print u'这⾥里里实在测试⾃自定义脚本,实现⾃自⼰己的逻辑'
使用
初始化:(venv) python manage.py db init 这个命令会在项目下创建 migrations 文件夹,所有迁移脚本都存放其中。 创建第一个版本:(venv) $ python manage.py db migrate -m "initial migration" 检查migrations\versions,会新建一个版本.py,检查里面表格及字段 运行升级 (venv) $ python manage.py db upgrade,会把项目使用的数据库文件,更新为新的表格、字段,同时保留数据

浙公网安备 33010602011771号