第一章
1.1 Hello,Flask!
app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return '<h1>Hello Flask!</h1>'
1.1.1 创建示例程序
我们安装Flask时,他会在Python解释器中创建一个flask包,我们可以通过flask包的构造文件导入所有开放的类和函数。我们先从flask包中导入Flask类,这个类代表一个Flask程序。实例化这个类,就得到我们的程序实例app:
from flask import Flask
app = Flask(__name__)
传入Flask构造方法的第一个参数是模块或者包的名称,我们应该使用特殊变量 __ name __. __
Python会根据所处的模块来赋予 __ name __变量相应的值,对于我们程序来说,这个值为app
1.1.2 注册路由
在一个Web应用中,客户端和服务器上的Flask程序的交互可以简单概括为以下几步:
1)用户在浏览器输入URL访问某个资源
2)Flask接收用户的请求并分析请求的URL
3)为这个URL找到对应的处理函数
4)执行函数并生成响应,返回给浏览器
5)浏览器接收并解析响应,将信息显示在页面中
在上面这些步骤中,大部分由Flask完成。我们需要做的只是建立处理请求的函数,并为其定义对应的URL规则。只需为函数附加app.route()装饰器,并传入URL规则作为参数,我们就可以让URL与函数建立关联。这个过程我们称为注册路由(route),路由负责管理URL和函数之间的映射,而这个函数则被成为视图函数(view function)
-
路由的含义可以从字面理解,作为动词时,他的含义是“按某路线发送”,即调用与请求URL对应的试图函数。
在这个程序中,app.route()装饰器把根地址/和index()函数绑定起来,当用户访问这个URL时就会触发index()函数。视图函数index()返回一行问候
@app.route('/') def index(): return '<h1>Hello, World!</h1>'
route()装饰器的第一个参数是URL规则,用字符串表示,必须以/开始。这里的URL是相对的URL(又称内部URL),即不包含域名的URL,以域名www.baidu.com为例,“/”对应的是根地址,即www.baidu.com,如果把URL规则改为“/hello”,则实际的绝对地址为www.baidu.com/hello
为视图绑定多个URL
一个视图函数可以绑定多个URL。比如下面的代码把/hi和/hello都绑定到say_hello()函数上,着就会为say_hello()视图注册两个路由,当用户访问这两个URL中的任意一个,均会触发say_hello()函数
@app.route('/hi') @app.route('/hello') def say_hello(): return '<h1>Hello, Flask!</h1>'
动态函数
我们不仅可以为视图函数绑定多个URL,还可以在URL规则中添加变量部分,使用“<"变量名>"的形式表示。Flask处理请求时会把变量传入视图函数,所以我们可以添加承诺书获取这个变量值。视图函数greet(),他的URL规则包含一个name变量
@app.route('/greet/<name>') def greet(name): return '<h1>Hello, %s!</h1>' % name
因为URL中可以包含变量,所以将传入app.route()字符串成为URL规则,而不是URL,Flask会解析请求并把请求的URL与视图函数的URL规则进行匹配。比如,这个greet视图URL规则为/greet/<name>,那么类似greet/foo、greet/bar的请求都会触发这个视图函数
当URL规则中包含变量时,如果用户访问URL中没有添加变量,比如/greet,那么Flask在匹配失败后会返回一个404错误响应。一个很常见的行为实在app.route()装饰器使用defaults参数设置URL变量的默认值,这个参数接收字典作为输入,存储在URL变量和默认值的映射。在下面的代码中,我们为greet视图新添加了一个app.route()装饰器,为/greet设置了默认的name值:
@app.route('/greet',defaults={'name':'Programmer'}) @app.route('/greet/<name>') def greet(name): return "<h1>Hello, %s</h1>" % name
这时如果用户访问/greet,那么变量name会使用默认值Programmer。视图函数返回<h1>Hello, Programmer!</h1>
实际效果等同于:
1.2 启动开发服务器
1.2.1 Run,Flask, Run!
Flask通过依赖包Click内置了一个CLI(命令行交互界面),当我们安装Flask后,会自动添加一个flask命令脚本,我们可以通过flask命令执行内置命令,扩展提供的命令或者我们自定义的命令。其中flask Run命令用来启动内的开发服务器
-
flask run
执行flask --help查看所有可用的命令
-
如果执行flask run命令后显示命令未找到提示(command found)或显示其他错误,可以尝试使用python -m flask run命令尝试解决
flask run命令运行的开发服务器默认监听http:// 127.0.0.1:5000/地址并开启多线程支持。
自动发现程序实例
一般来说,执行flask run命令运行程序前,我们需要提供程序实例所在模块的位置。我们在上面可以直接运行程序,因为Flask会自动探测程序实例,自动探测存在下面这些规则
- 从当前目录寻找app.py和wsgi.py模块,并从中寻找名为app或application的程序实例。
- 从环境变量FLASK_APP对应的值寻找名为app或application的程序实例
因为我们程序主模块命名为app.py,所以flask run命令会自动在其中寻找程序实例。如果你的程序主模块是其他名称,比如hello.py,那么需要设置环境变量FLASK_APP,将包含程序实例的模块名赋值给这个变量,Linux或macOS系统使用export命令:
export FLASK_APP = hello
在windows中使用set命令
set FLASK_APP = hello
管理环境变量
创建.env和.flaskenv文件管理环境变量
- .flaskenv文件用来存储和Flask相关的公共环境变量
- .env用来存储包含敏感信息的环境变量
使用方式如下所示:
SOME_VAR = 1
这是注释
FOO='BAR'
1.2.2 更多启动选项
使服务器外部可见
我们在上面启动的Web服务器默认是对外不可见的,可以在run命令后田间 --host 选项将主机地址设为0.0.0.0使其对外可见:
- flask run --host=0.0.0.0
这会让服务器监听所有外部请求,个人计算机一般没有公网IP,所以,你的程序只能被局域网内的其他用户通过你的个人计算机的内网ip访问,比如,你的内网ip为192.168.31.1,当局域网内的其他用户访问192.168.31.1:5000时,也会看到浏览器显示内容
改变默认端口
Flask提供的Web服务器会默认监听5000端口,你可以在启动时传入参数来改变他:
- flask run --port=8000
1.2.3 设置运行环境
开发环境:
指我们在本地编写和测试程序时的计算机环境
生产环境 :
网站部署上线供用户访问时的服务器环境
根据运行环境的不同,Flask程序、扩展以及其他程序会改变相应的行为和设置。为了区分程序运行环境,Flask提供了一个FLASK_ENV环境变量用来设置环境,默认为production(生产)。在开发时,我们可以将其设为development(开发),这会开启所有支持开发的特性。为了方便管理,我们将把环境变量FLASK_ENV的值写入.flskenv文件中:
FLASK_ENV = development
1.3 项目配置
在很多情况下,你需要设置程序的某些行为,这时你就需要使用配置变量。在Flask中。配置变量就是一些大写形式的Python变量,你也可以称之为配置参数或配置建。使用统一的配置变量可以避免在程序中以硬编码的形式设置程序
加载配置方式一:
app.config['ADMIN_NAME'] = 'Perter'
-
配置的名称必须是全大写形式,小写的变量将不会被加载、读取
加载配置方式二:
app.config.update(
TESTION=True,
SECRET_KEY = 'sdfrgghjjkh7r'
)
加载配置方式三:从config字典里通过将配置变量的名称作为键读取对应的值
value = app.config['ADMIN_NAME]
1.4 URL与端点
在Web程序中,URL无处不在。如果程序中的URL都是以硬编码的方式写出,那么将会大大降低代码的易用性。比如当你修改了某个路由的URL规则,那么程序里对应的url都要一个个修改,
更好的解决方法是使用Flask使用的url_for()获取URL,当路由中定义的URL规则被修改时,这个函数会返回正确的URl
调用url_for()函数时,第一个参数为端点值。在Flask中,端点用来标记一个视图函数以及对应的URL规则。端点的默认值为视图函数的名称。
例如下面的函数:
@app.route('/')
def index():
return 'Hello Flask!'
这个路由的端点即视图函数的名称index,调用url_for('index'),即可获取对应的URL,即(‘/’)
-
在app.route()装饰器中使用endpoint参数可以自定义端点值,不过我们一般不建议这样使用
如果URL含有动态部分,那么我们需要在url_for()函数中传入相应的参数,以下面的函数为例:
@app.route('/hello/<name>')
def greet(name):
return 'hello %s!' % name
这时使用url_for('say_hello',name="Jack")得到的URL为‘/hello/Jack’
1.5 Flask命令
除了Flask内置的flask run等命令,我们也可以自定义命令。在虚拟环境安装flask后,包含许多内置命令的flsk就可以使用了。
通过创建一个函数,并为其添加app.cli.command()装饰器,我们就可以注册一个新的命令。如下所示
@app.cli.command()
def hello():
click.echo('hello, Human!')
函数的名称即为命令名称,这里注册的命令即hello,你可以使用flask hello命令来触发。作为替代,你也可以在app.cli.command()装饰器中传入参数设置命令名称,比如app.cli.command('say-hello')会把命令名称设置为say-hello,完整的命令即flask say-hello
借助click模块的flask --help可以查看Flask提供的命令帮助文档,我们自定义的hello命令也会出现在输出命令列表中
1.6 模板与静态文件
我们需要模板和静态文件来声称更加丰富的网页。模板即包含程序页面的HTML文件,静态文件是需要在HTML文件中加载的CSS和JS文件,以及图片、字体文件等资源文件。默认情况下,模板文件存放在项目根目录中的templates文件夹中,静态文件存放在static文件夹下,这两个文件需要和八平汉程序实例的模块处于同意文件夹下,结构如下:
hello/
- templates
- static
- app.py