Python–Web应用程序框架(Flask)–基础
Web Application Framework(Web应用程序框架)或简单的Web Framework(Web框架)表示一个库和模块的集合,使Web应用程序开发人员能够编写应用程序,而不必担心协议,线程管理等低级细节。
Flask是一个用Python编写的Web应用程序框架。让我们可以使用Python语言快速实现一个网站或Web服务,在介绍Flask之前首先来聊下它和Django的联系以及区别,django是个大而全的web框架,它内置许多模块,flask是一个小而精的轻量级框架,Django功能大而全,Flask只包含基本的配置, Django的一站式解决的思路,能让开发者不用在开发之前就在选择应用的基础设施上花费大量时间。Django有模板,表单,路由,基本的数据库管理等等内建功能。与之相反,Flask只是一个内核,默认依赖于2个外部库: Jinja2 模板引擎和 WSGI工具集–Werkzeug , flask的使用特点是基本所有的工具使用都依赖于导入的形式去扩展,flask只保留了web开发的核心功能。
Web Server Gateway Interface(Web服务器网关接口,WSGI)是已被用作Python Web应用程序开发的标准。 WSGI是Web服务器和Web应用程序之间通用接口的规范。
WSGI工具包实现了请求,响应对象和实用函数。 这使得能够在其上构建web框架。 Flask框架使用Werkzeug作为其基础之一。
jinja2是Python的一个流行的模板引擎。Web模板系统将模板与特定数据源组合以呈现动态网页。
Flask通常被称为微框架。 它旨在保持应用程序的核心简单且可扩展。Flask没有用于数据库处理的内置抽象层,也没有形成验证支持。相反,Flask支持扩展以向应用程序添加此类功能。
一、Flask应用
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World'
if __name__ == '__main__':
app.run()
必须在项目中导入Flask模块。
Flask类的一个对象是我们的WSGI应用程序。
Flask构造函数使用**当前模块(__name __)**的名称作为参数。__name__
这个特殊的参数:Python会根据所处的模块来赋予__name__
变量相应的值。
Flask类的**route()**函数是一个装饰器,它告诉应用程序哪个URL应该调用相关的函数。@app.route('/')
就是用来匹配url的,在我们的flask里面是以装饰器来实现的,装饰器引用的也是我们上面实例化核心类出来的对象。非装饰器形式可由下表示:
def hello_world():
return 'hello world'
app.add_url_rule('/', 'hello', hello_world)
函数:
app.route(rule, options)
- rule 参数表示与该函数的URL绑定。
- options 是要转发给基础Rule对象的参数列表。
在上面的示例中,'/ ’ URL与**hello_world()**函数绑定。
因此,当在浏览器中打开web服务器的主页时,将呈现该函数的输出。
最后,Flask类的**run()**方法在本地开发服务器上运行应用程序。
app.run(host, port, debug, options)
序号 | 参数与描述 |
---|---|
1 | host 要监听的主机名。 默认为127.0.0.1(localhost)。设置为“0.0.0.0”以使服务器在外部可用 |
2 | port 默认值为5000 |
3 | debug 默认为false。 如果设置为true,则提供调试信息 |
4 | options 要转发到底层的Werkzeug服务器。 |
执行上述python脚本,可在浏览器中打开上述URL(local host:5000),浏览器将显示“Hello World”
http://127.0.0.1:5000/
二、Flask静态资源
在Python中,static
目录通常用于存放静态文件,如图像、样式表、JavaScript文件等。静态文件是在Web应用程序中不经常更改的文件,与动态生成的内容相对。
在许多Web框架中,例如Django和Flask,static
目录是默认的静态文件目录。当你将静态文件放置在static
目录中时,Web应用程序可以直接从该目录中提供这些文件,而不需要通过动态生成的路由处理。
以下是一个典型的使用static
目录的目录结构示例:
myapp/
├── static/
│ ├── css/
│ │ └── styles.css
│ ├── js/
│ │ └── script.js
│ └── images/
│ └── logo.png
└── app.py
在这个例子中,static
目录位于应用程序的根目录下。它包含了三个子目录:css
、js
和images
,分别用于存储样式表、JavaScript文件和图像文件。
以下是一个使用Flask展示了如何使用static
目录存放静态文件:
from flask
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
# return render_template('index.html', css_url='static/htmls/xxxx')
if __name__ == "__main__":
app.run()
在上述示例中,index.html
是一个静态文件,位于static
目录中。app.send_static_file()
方法用于返回静态文件,这样当用户访问根路径时,将会返回index.html
。
请注意,具体使用方式可能因框架或应用程序而异。在开发Web应用程序时,你可以根据需要创建自己的static
目录,并将静态文件放置其中。
静态资源的另一种调用方式:
from flask import Flask, render_template
app = Flask(__name__, template_folder="templates", static_folder="static", static_url_path="/static")
# template_folder:指定HTML文件查找目录
# static_folder:指定静态资源存放目录
# static_url_path:HTML中静态资源的标志
# 装饰器形式
# @app.route("/index")
# def index():
# return render_template("index.html")
# 非装饰器形式
def index():
return render_template('index.html')
app.add_url_rule('/index', 'index', index)
if __name__ == '__main__':
app.run()
如上所示,使用Flask直接创建,不传入 static_folder参数的话 ,默认的静态文件的位置是在 static目录下。
这是Flask的 __init__源码:
def __init__(
self,
import_name,
static_url_path=None,
static_folder='static',
static_host=None,
host_matching=False,
subdomain_matching=False,
template_folder='templates',
instance_path=None,
instance_relative_config=False,
root_path=None
):
_PackageBoundObject.__init__(
self,
import_name,
template_folder=template_folder,
root_path=root_path
)
if static_url_path is not None:
self.static_url_path = static_url_path
if static_folder is not None:
self.static_folder = static_folder
可以看到 static_folder 是默认为 static的;之所以能够访问到 static下面的静态文件,是因为注册了路由,就和flask的 app.route一样。
app = Flask(__name__, static_folder='spider', static_url_path='/spider/1')
这句话的意思就是 我们可以spider文件下的静态文件,但是我们访问的方式为:
127.0.0.1:5000/spider/1/xxx.xxx
三、Flask–蓝图(Blueprint )
蓝图是一种组织 Flask 应用程序的方式,将应用程序划分为多个模块并使其易于管理。Blueprint 是一个存储操作方法的容器,这些操作在这个Blueprint 被注册到一个应用之后就可以被调用,Flask 可以通过Blueprint来组织URL以及处理请求。
Flask使用Blueprint让应用实现模块化,在Flask中,Blueprint具有如下属性:
- 一个应用可以具有多个Blueprint;
- 可以将一个Blueprint注册到任何一个未使用的URL下比如 “/”、“/sample”或者子域名;
- 在一个应用中,一个模块可以注册多次;
- Blueprint可以单独具有自己的模板、静态文件或者其它的通用操作方法,它并不是必须要实现应用的视图和函数的;
- 在一个应用初始化时,就应该要注册需要使用的Blueprint;
但是一个Blueprint并不是一个完整的应用,它不能独立于应用运行,而必须要注册到某一个应用中。
注册蓝图(Blueprint)用app.register_blueprint() 方法:
from flask import Blueprint, render_template
# 创建一个蓝图对象
bp = Blueprint('my_blueprint', __name__)
# 在蓝图上定义路由和视图函数
@bp.route('/hello')
def hello():
return 'Hello, World!'
@bp.route('/greet/<name>')
def greet(name):
return 'Hello, {}'.format(name)
# 在应用程序对象上注册蓝图
app = Flask(__name__)
app.register_blueprint(bp, url_prefix='/myapp')
1.创建了一个蓝图对象 bp,并在该蓝图对象上定义了两个路由和视图函数。
2.app.register_blueprint() 方法将该蓝图对象 bp 注册到应用程序对象 app 上,并指定前缀为 /myapp。
3.运行该程序可以通过访问 /myapp/hello 和 /myapp/greet/xxx 来访问蓝图中定义的路由。
蓝图运行机制:
- 蓝图是保存了一组将来可以在应用对象上执行的操作,注册路由就是一种操作;
- 当在应用对象上调用 route 装饰器注册路由时,这个操作将修改对象的url_map路由表;
- 然而,蓝图对象根本没有路由表,当我们在蓝图对象上调用route装饰器注册路由时,它只是在内部的一个延迟操作记录列表defered_functions中添加了一个项;
- 当执行应用对象的 register_blueprint() 方法时,应用对象将从蓝图对象的 defered_functions 列表中取出每一项,并以自身作为参数执行该匿名函数,即调用应用对象的 add_url_rule() 方法,这将真正的修改应用对象的路由表;
蓝图的url前缀
- 当我们在应用对象上注册一个蓝图时,可以指定一个url_prefix关键字参数(这个参数默认是/);
- 在应用最终的路由表 url_map中,在蓝图上注册的路由URL自动被加上了这个前缀,这个可以保证在多个蓝图中使用相同的URL规则而不会最终引起冲突,只要在注册蓝图时将不同的蓝图挂接到不同的自路径即可;
url和路由的区别
我们调用接口需要调用的是一段具体的代码,也就是一个python类或者python函数,而url就是对这段代码的具体映射,也就是说我们可以通过url找到一个具体的python类或者python函数,这便是url。而路由是根据url定位到具体的pyhon类或python函数的程序,这段程序我们称之为路由。
在Flask程序中使用路由我们称之为注册路由,是使用程序实例提供的app.route()装饰器注册路由,而括号内的字符串就是url,注册路由的过程就是完成了 url和python类或函数映射的过程,可以理解为会有一张表保存了url与python类或函数的对应关系。这样我们以url访问flask就可以找到对应的程序。