
- 认识Flask
- Flask扩展包
- Flask创建app对象
- Flask的使用演示
- 初始化参数
- 配置参数的使用
- 读取配置参数
- app.run()的参数
- 路由
- 设置请求方式
- 同一url对应不同视图函数
- 同一视图函数对应多个url
- url反向解析
- 动态路由(转换器)
- 获取请求参数
- 上传文件
- abort()函数
- 自定义异常处理方法
- 自定义响应信息
- 使用元组
- 使用make_response
- 返回json数据
- cookie和session
- cookie的使用
- session的使用
- 上下文对象
- 请求钩子
- Flask-Script扩展命令行
Flask本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login),都需要用第三方的扩展来实现。比如可以用Flask-extension加入ORM、窗体验证工具,文件上传、身份验证等。Flask没有默认使用的数据库,你可以选择MySQL,也可以用NoSQL。其WSGI工具箱采用Werkzeug(路由模块),模板引擎则使用Jinja2。可以说Flask框架的核心就是Werkzeug和Jinja2
英文文档:https://flask.palletsprojects.com/en/0.12.x/
中文文档:http://docs.jinkan.org/docs/flask/
Flask-SQLalchemy: *** 作数据库
Flask-migrate:管理迁移数据库
Flask-Mail:邮件
Flask-WTF:表单
Flask-script:插入脚本
Flask-Login:认证用户状态
Flask-RESTful:开发REST API的工具
Flask-Bootstrap:集成前端Twitter Bootstrap框架
Flask-Moment:本地化日期和时间
from flask import Flask
# 创建flask的应用对象,__name__表示的是当前模块的名字,、
# 模块名,flask以这个模块所有的目录为总目录,默认这个目录中的static为静态目录,templates为模板目录
app = Flask(__name__)
# app = Flask('__main__') # 和上面效果相同
# app = Flask('abcdefgh') # 当模块名不存在时Flask会自动将当前模块作为启动模块
# 使用应用对象的route()方法做装饰器,参数为视图函数对应的url,
# 作用是将路由映射到视图函数index
@app.route('/')
def index():
"""定义视图函数"""
# 直接返回内容到前端页面
return 'hello flask'
if __name__ == '__main__':
# 使用应用对象的run()方法启动Web服务器
app.run()
Flask程序的启动:直接运行此程序即可
初始化参数import_name:导入路径(寻找静态目录与模板目录位置的参数)
static_url_path:访问静态资源的url前缀,默认值是static
static_folder:静态文件存放的目录,默认值是static
template_folder:模板文件存放的目录,默认值是templates
app = Flask(
__name__, # 导入路径(寻找静态目录与模板目录位置的参数)
static_url_path='/python', # 访问静态资源的url前缀,默认值是static
static_folder='static', # 静态文件存放的目录,默认值是static
template_folder='templates', # 模板文件存放的目录,默认值是templates
)
配置参数的使用
1> 从文件中导入配置项:app.config.from_pyfile('config.cfg')
2> 从对象中导入配置项:app.config.from_object(Config)
3> 直接 *** 作config的字典对象:app.config['DEBUG'] = True
直接从全局对象app的config字典中取值:app.config.get('TEST_ATTR')
通过current_app获取参数,使用方式和app相同
from flask import current_app
current_app.config.get('TEST_ATTR')
app.run()的参数
app.run() # 参数为默认值,只可以通过127.0.0.1访问
app.run(host='192.168.xx.xxx', port=5000) # 只可以通过192.168.xx.xxx访问
app.run(host='0.0.0.0', port=5000) # 使用127.0.0.1和192.168.xx.xxx均可访问
app.run(host='0.0.0.0', port=5000, debug=True) # debug参数可以在启动时设置,其他参数不行
路由
通过url_map属性查看所有的路由信息:app.url_map
视图函数默认的请求方式为:OPTIONS、HEAD和GET,可以在route()装饰器中通过methods参数设置请求方式
@app.route('/post_only', methods=['GET', 'POST'])
def post_only():
return 'post only page'
同一url对应不同视图函数
可以使用不同的请求方式进行区分,如果请求方式也相同,则上面的视图函数会覆盖下面的视图函数
@app.route('/hello', methods=['POST'])
def hello1():
return 'hello 1'
@app.route('/hello')
def hello2():
return 'hello 2'
同一视图函数对应多个url
多次使用route()装饰器对视图函数进行装饰即可
@app.route('/hi1')
@app.route('/hi2')
def hi():
return 'hi page'
url反向解析
使用redirect和url_for函数实现url的反向解析,
url_for函数可以通过视图函数的名字找到其对应的url路径
from flask import Flask, redirect, url_for
@app.route('/login')
def login():
url = url_for('index')
return redirect(url)
动态路由(转换器)
在Flask中可以通过转换器提取url中的参数
# 路由传递的参数默认当做string处理,尖括号中冒号后面的参数名可以自定义
# @app.route('/goods/')
@app.route('/goods/' ) # 不加转换器类型,默认是字符串规则(除了`/`)
def goods_detail(goods_id):
return 'goods detail page %s' % goods_id
转换器的种类有:
| int | 接受整数 |
|---|---|
| float | 接受浮点数 |
| path | 和默认的相似,但也可以接受斜线 |
- 自定义转换器
通过自定义一个继承自werkzeug.routing.BaseConverter的类可以实现自定义转换器# 1.定义转换器 class RegexConverter(BaseConverter): def __init__(self, url_map, regex): # 调用父类的初始化方法 super().__init__(url_map) # 将正则表达式的参数保存到对象的regex属性中,flask会使用这个属性进行路由的正则匹配 self.regex = regex # 2.将自定义的转换器添加到flask的应用中 app.url_map.converters['re'] = RegexConverter # 3.使用自定义的转换器,传入正则表达式 @app.route('/send/' ) def send_sms(mobile): return 'send sms to %s' % mobile
from flask import request
request对象中保存了一次HTTP请求的一切信息,request常用的属性如下:
| 属性 | 说明 | 类型 |
|---|---|---|
| data | 记录请求体中的数据,并转换为字符串 | * |
| form | 记录请求中的表单数据 | MultiDict |
| args | 记录请求中的查询字符串 | MultiDict |
| cookies | 记录请求中的cookie信息 | Dict |
| headers | 记录请求中的报文头 | EnvironHeaders |
| method | 记录请求使用的HTTP方法 | GET/POST |
| url | 记录请求的url地址 | string |
| files | 记录请求上传的文件 | * |
from flask import request
@app.route('/index', methods=['GET', 'POST'])
def index():
# 使用request.form可以直接提取请求体中表单格式的数据,是一个类字典的对象
# 通过get()方法只能拿到多个同名参数的第一个
name = request.form.get('name')
age = request.form.get('age')
# 通过getlist()方法可以获取多个同名的参数,返回一个字典
name_list = request.form.getlist('name')
# request.data可以获取请求体中的数据
print('request.data:%s' % request.data)
# args可以提取url中的查询字符串(`?`后面的)
city = request.args.get('city')
return 'hello name=%s, age=%s, city=%s' % (name, age, city)
上传文件
使用request对象的files属性可以获取到上传的文件,同时可以使用文件对象的save()方法将文件保存下来
from flask import request
@app.route('/upload', methods=['POST'])
def upload():
file_obj = request.files.get('pic')
if file_obj is None:
return '未上传文件'
file_obj.save('demo.png') # 使用上传的文件对象的save()方法保存文件
return '上传成功!'
abort()函数
使用abort()函数可以立即终止视图函数的执行,并返回给前端特定的信息。常用于返回标准状态码对应的页面或者响应体信息
from flask import Flask, abort, Response
@app.route('/login', methods=['GET'])
def login():
name = ''
pwd = ''
if name != 'zhangsan' or pwd != 'admin':
# 1.返回状态码对应的页面,必须是标准的HTTP状态码
# abort(404)
# 2.返回响应体信息
abort(Response('登录失败!'))
return '登录成功!'
自定义异常处理方法
通过自定义异常处理方法可以在前端页面上显示自定义的异常提示信息
# 在出现404错误时,将会使用此异常处理方法
@app.errorhandler(404)
def handle_404_error(err):
# 这个函数的返回值会是出现404错误时前端显示的结果
return '出现了404错误,错误信息:%s' % err
自定义响应信息
使用元组
使用元组设置自定义的响应信息,元组的构成为:(response, status, headers)
响应头headers可以使用列表或字典的方式进行设置
状态码status可以是非标准的,同时可以使用字符串设置说明信息
响应头headers可以不写,但是状态码不能单独省略,即可以从后向前省略,不能从中间省略
@app.route('/index')
def index():
# 响应头headers可以使用列表或字典的方式进行设置
# return 'index page', 400, [('study', 'python'), ('city', 'beijing')]
# return 'index page', 400, {'study1': 'python1', 'city1': 'beijing1'}
# 状态码status可以是非标准的,同时可以使用字符串设置说明信息
# return 'index page', 666, {'study1': 'python1', 'city1': 'beijing1'}
# return 'index page', '666 python study', {'study1': 'python1', 'city1': 'beijing1'}
# 响应头headers可以不写,但是状态码不能单独省略,即可以从后向前省略,不能从中间省略
return 'index page', '666 python study'
使用make_response
使用make_response设置响应信息需要从flask中导入make_response
from flask import Flask, make_response
@app.route('/index')
def index():
resp = make_response('index page 2') # 设置响应体
resp.status = '999 python' # 设置状态码
resp.headers['city'] = 'shanghai' # 设置响应头
resp.headers['name'] = 'lisi' # 设置响应头
return resp # 返回响应信息
返回json数据
从flask中导入jsonify,jsonify可以将字典转化为json数据,并将响应头中的Content-Type的值设置为application/json
from flask import Flask, jsonify
@app.route('/index')
def index():
data = {'name': 'libai', 'age': 23}
# return jsonify(data) # 方式一
return jsonify(city='beijing', name='dufu') # 方式二
cookie和session
cookie的使用
from flask import Flask, make_response, request
app = Flask(__name__)
# 设置cookie
@app.route('/set_cookie')
def set_cookie():
resp = make_response('success')
# 设置cookie,默认有效期是临时cookie,浏览器关闭就失效
resp.set_cookie('city1', 'shanghai')
# 设置过期时间,单位秒
resp.set_cookie('city2', 'luoyang', max_age=3600)
return resp
# 获取cookie
@app.route('/get_cookie')
def get_cookie():
c = request.cookies.get('city1')
return c
# 删除cookie
@app.route('/del_cookie')
def del_cookie():
resp = make_response('del success')
resp.delete_cookie('city1')
return resp
session的使用
flask中使用session需要设置秘钥字符串,并且默认的是将session保存在cookie中,可以通过另外的设置将session保存到数据库中
from flask import Flask, session
app = Flask(__name__)
# 设置秘钥字符串,用于加密和防篡改
app.config['SECRET_KEY'] = 'alknfhk89adfwer234sd2'
# 设置session,flask默认把session保存到cookie中
@app.route('/login')
def login():
session['name'] = 'python'
session['tel'] = '18612345678'
return 'login success'
# 获取session
@app.route('/index')
def index():
name = session.get('name')
return 'hello %s' % name
上下文对象
- 请求上下文(request context):
request和session都属于请求上下文对象 - 应用上下文(application context):
current_app和g都属于应用上下文对象
current_app:表示当前运行的程序文件的程序实例
g:处理请求时用于临时存储的对象,每次请求都会重设这个变量
请求钩子是通过装饰器的形式实现的,Flask支持如下四种请求钩子:
1> @app.before_first_request:在处理第一次请求之前被执行
2> @app.before_request:在每次处理请求之前都被执行
3> @app.after_request:在每次请求(视图函数处理)之后都被执行,前提是视图函数不出现异常
4> @app.teardown_request:在每次请求(视图函数处理)之后都被执行,无论视图函数是否出现异常都会执行;当出现异常时,只有在非调试模式时才会被执行
注:@app.after_request和@app.teardown_request装饰的函数需要一个参数接收请求处理之后返回的结果,并且在函数结束时将这个结果返回回去
安装:pip install Flask-Script
通过使用Flask-Script扩展,可以实现在终端中启动Flask程序,通过命令行的方式传入参数
如下面的代码就可以在终端中通过python demo.py runserver命令进行启动
# demo.py
from flask import Flask
from flask_script import Manager # 启动命令的管理类
app = Flask(__name__)
# 创建Manager管理类的对象
manager = Manager(app)
@app.route('/index')
def index():
return 'index page -manager'
if __name__ == '__main__':
manager.run() # 通过管理对象启动Flask
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)