1. 圈地,打地基,盖楼,装修,入驻
2. 买楼,装修,入驻
总结:降低开发难度,提高开发效率,不需要重复造轮子
django
特点:大而全 自带的功能特别特别特别的多 类似于航空母舰
不足之处: 有时候过于笨重
flask
特点:小而精 自带的功能特别特别特别的少 类似于游骑兵
第三方的模块特别特别特别的多,如果将flask第三方的模块加起来完全可以盖过django
并且也越来越像django
不足之处:
比较依赖于第三方的开发者
tornado
特点:异步非阻塞 支持高并发
牛逼到甚至可以开发游戏服务器
A:socket部分
B:路由与视图函数对应关系(路由匹配)
C:模版语法
django
A用的是别人的 wsgiref模块
B用的是自己的
C用的是自己的(没有jinja2好用 但是也很方便)
flask
A用的是别人的 werkzeug(内部还是wsgiref模块)
B自己写的
C用的别人的(jinja2)
tornado
A,B,C都是自己写的
诞生时间:Flask诞生于2010年,是Armin ronacher(人名)用 Python 语言基于 Werkzeug工具箱编写的轻量级Web开发框架。
Flask框架包含两个核心:Werkzeug工具箱,Jinja2模板引擎
由于Flask没有提供额外的其他功能,所以几乎所有的功能都要用到扩展实现,如下列表所示:
Flask-SQLalchemy:操作数据库;
Flask-script:插入脚本;
Flask-migrate:管理迁移数据库;
Flask-Session:Session存储方式指定;
Flask-WTF:表单;
Flask-Mail:邮件;
Flask-Bable:提供国际化和本地化支持,翻译;
Flask-Login:认证用户状态;
Flask-OpenID:认证;
Flask-RESTful:开发REST API的工具;
Flask-Bootstrap:集成前端Twitter Bootstrap框架;
Flask-Moment:本地化日期和时间;
Flask-Admin:简单而可扩展的管理接口的框架
更多扩展列表
flask中文文档
flask英文文档
Web应用程序作用
Web(World Wide Web)诞生最初的目的,是为了利用互联网交流工作文档。
一切从客户端发起请求开始。
Flask程序运行过程:
所有Flask程序必须有一个程序实例。
Flask调用视图函数后,会将视图函数的返回值作为响应的内容,返回给客户端。一般情况下,响应内容主要是字符串和状态码。
当客户端想要获取资源时,一般会通过浏览器发起HTTP请求。此时,Web服务器使用WSGI(Web Server Gateway Interface)协议,把来自客户端的所有请求都交给Flask程序实例。WSGI是为 Python 语言定义的Web服务器和Web应用程序之间的一种简单而通用的接口,它封装了接受HTTP请求、解析HTTP请求、发送HTTP,响应等等的这些底层的代码和操作,使开发者可以高效的编写Web应用。
程序实例使用Werkzeug来做路由分发(URL请求和视图函数之间的对应关系)。根据每个URL请求,找到具体的视图函数。 在Flask程序中,路由的实现一般是通过程序实例的route装饰器实现。route装饰器内部会调用add_url_route()方法实现路由注册。
调用视图函数,获取响应数据后,把数据传入HTML模板文件中,模板引擎负责渲染响应数据,然后由Flask返回响应数据给浏览器,最后浏览器处理返回的结果显示给客户端
# 导入Flask类
from flask import Flask
#Flask类接收一个参数__name__
app = Flask(__name__)
# 装饰器的作用是将路由映射到视图函数index
@app.route('/')
def index():
return 'Hello World'
# Flask应用程序实例的run方法启动WEB服务器
if __name__ == '__main__':
app.run()
在程序运行过程中,程序实例中会使用 url_map 将装饰器路由和视图的对应关系保存起来,打印结果如下图:
Map([<Rule '/static/' (GET, HEAD, OPTIONS) -> static>,
<Rule '/' (GET, HEAD, OPTIONS) -> test>])
Flask 程序实例在创建的时候,需要默认传入当前 Flask 程序所指定的包(模块),接下来就来详细查看一下 Flask 应用程序在创建的时候一些需要我们关注的参数:
app = Flask(__name__)
def __init__(self, import_name, static_path=None, static_url_path=None,
static_folder='static', template_folder='templates',
instance_path=None, instance_relative_config=False,
root_path=None):
import_name
:Flask程序所在的包(模块),传__name__
就可以,其可以决定 Flask 在访问静态文件时查找的路径
static_url_path
:静态文件访问路径,可以不传,默认为:/ + static
static_folder
: 静态文件存储的文件夹,可以不传,默认为 static
template_folder
:模板文件存储的文件夹,可以不传,默认为 templates
在 Flask 程序运行的时候,可以设置相关配置比如:配置 Debug 模式,配置数据库连接地址等,设置 Flask配置有以下三种方式:
从配置对象中加载(常用)
app.config.from_object()
从配置文件中加载
app.config.from_pyfile()
从环境变量中加载(了解)
app.config.from_envvar()
从配置对象中加载,或者配置文件,或者环境变量中,加载配置信息,代码如下:
#1.导入Flask类
from flask import Flask
#2.创建Flask对象接收一个参数__name__,它会指向程序所在的包
app = Flask(__name__)
# 配置对象,里面定义需要给 APP 添加的一系列配置
class Config(object):
DEBUG = True
# 从配置对象中加载配置
app.config.from_object(Config)
# 从配置文件中加载配置
#app.config.from_pyfile('config.ini')
# 加载指定环境变量名称所对应的相关配置
#app.config.from_envvar('FLASKCONFIG') # FLASKCONFIG 也是文件,与config.ini类似
#3.装饰器的作用是将路由映射到视图函数index
@app.route('/')
def index():
return 'Hello World'
#4.Flask应用程序实例的run方法,启动WEB服务器
if __name__ == '__main__':
app.run()
可以指定运行主机的ip 端口 DEBUG等。
app.run(host="0.0.0.0", port=5000, debug = True)
路由、路径、参数、请求方式等。
# 指定访问视图函数demo1,访问路径为/demo1
@app.route('/demo1')
def demo1():
return 'demo1'
有时我们需要将同一类 URL 映射到同一个视图函数处理,比如:使用同一个视图函数来显示不同用户的个人信息。
# 路由传递参数,整数
@app.route('/user/' )
def user_info(user_id):
return 'the num is %d' % user_id
# 路由传递参数,字符串,不指定path默认就是字符串
@app.route('/user/' )
def user_info(user_id):
return 'hello %s' % user_id
提示:之所以int,path可以接收整数,字符串,是由于werkzeug提供了IntegerConverter,PathConverter
对应转换器.
系统自带转换器:
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
在 Flask 中,定义一个路由,默认的请求方式为:
如果想添加请求方试,那么可以使用methods指定,比如:
@app.route('/demo2', methods=['GET', 'POST'])
def demo2():
# 直接从请求中取到请求方式并返回
return request.method
视图函数返回响应,主要有三种方式
1.字符串
1.直接返回响应体数据
return '字符串'
2.直接返回响应体数据+状态码
return '字符串',状态码
3.直接返回响应体数据+状态码+响应头信息
return '字符串',状态码,{
'key':'value'}
2.通过jsonify返回json数据
格式: jsonify(dict)
简化格式: jsonify(key=value,key2=value2)
request 就是flask中代表当前请求的 request 对象,其中一个请求上下文变量(理解成全局变量,在视图函数中直接使用可以取到当前本次请求)
常用属性:
"""
- request.args: 获取的是问号后面的查询参数
- request.method: 获取的请求方式
- request.url: 获取请求的地址
- request.files: 获取的是input标签中type类型为file的文件
"""
from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def hello_world():
print(request.method)
print(request.url)
print(request.args)
print(request.args["name"]) #字典不建议使用[]的方式取值
print(request.args.get("name")) #如果获取不到不会报错,返回None
print(request.args.get("age",39)) #如果获取不到,设置一个默认值
return "helloworld"
if __name__ == '__main__':
app.run(debug=True)
GET
http://127.0.0.1:5000/?name=laowang&age=12
ImmutableMultiDict([('name', 'laowang'), ('age', '12')])
laowang
laowang
12
"""
- 解释: 当访问正常视图函数的时候,顺带执行的方法
- 常见的请求钩子有四种:
- 1.before_first_request:在处理第一个请求前执行
- 2.before_request:在每次请求前执行,在该装饰函数中,一旦return,视图函数不再执行
- 3.after_request:如果没有抛出错误,在每次请求后执行
接受一个参数:视图函数作出的响应
在此函数中可以对响应值,在返回之前做最后一步处理,再返回
- 4.teardown_request:在每次请求后执行
接受一个参数:用来接收错误信息
"""
from flask import Flask
app = Flask(__name__)
# before_first_request装饰的函数在第一次访问的时候执行,里面适合做初始化操作,比如,io文件读写
@app.before_first_request
def before_first_request():
print("before_first_request")
# before_request,每次请求前都执行,适合对请求参数做校验,访问统计
@app.before_request
def before_request():
print("before_request")
# after_request,视图函数执行之后,返回该方法,适合对返回值做统一处理,比如:返回统一的json数据格式
@app.after_request
def after_request(resp):
print("after_request")
resp.headers["Content-Type"] = "application/json"
return resp
# teardown_request,请求销毁之后,执行该方法,适合做异常信息统计
@app.teardown_request
def teardown_request(e):
print(e)
print("teardown_request")
@app.route('/')
def hello_world():
return "helloworld"
@app.route('/index')
def index():
return "index"
if __name__ == '__main__':
app.run(debug=True)