欢迎阅读本教程。接下来你将开始学习如何以 Python 语言和 Flask 框架为工具来创建web程序。
(此处有视频展示了本教程的相关内容,因为是youtube的视频,故不予链接)。
操作系统:ubuntu20.04 desktop amd64,虚拟机vmware workstation 15.5.1
python:系统自带Python3
在本章,你将学到如何设置一个FLASK工程。在结尾处,你会在自己电脑上跑起来一个简单的Flask web应用!
- Chapter 1: Hello, World! (this article)
- Chapter 2: 模版
- Chapter 3: 表单
- Chapter 4: 数据库
- Chapter 5: 用户登录
- Chapter 6: 个人信息和 Avatars头像
- Chapter 7: 错误处理
- Chapter 8: 关注者
- Chapter 9: 分页
- Chapter 10: 邮件
- Chapter 11:外观改进
- Chapter 12: 日期与时间
- Chapter 13:国际化
- Chapter 14: Ajax
- Chapter 15: 更好的结构
- Chapter 16: 全文检索
- Chapter 17: 在Linux上部署
- Chapter 18: 在Heroku上部署
- Chapter 19: Docker容器部署
- Chapter 20: JavaScript 魔法
- Chapter 21: 用户提醒
- Chapter 22: 后台工作
- Chapter 23: 应用编程接口(APIs)
Note 1: 如果你要查看旧版本的教程, 点击 这里.
Note 2: 如果你想支持我的工作或者没有耐心等着看每周更新的文章,我还准备了一个完整的教程包如电子书或格式或视频合集。更多信息请看 我的课程 courses.miguelgrinberg.com.
本教程所有代码都在Github仓库中,如果不愿逐一输入,你可以直接下载对应章节的代码,——但,我强烈建议你自己输入一遍,起码开头的这些章节。在你熟悉Flask之后才可以直接阅读、利用现成的代码。
Python环境安装
如果电脑上没有Python,那就需要先安装一下。如果你的操作系统没有自带python包(linux系统标配python,最新版已经是3.x),那可以去 Python 官网下载安装程序。注意如果你在windows上使用WSL或者Cygwin模拟器,那不能使用原生的windows Python版本,而是应该通过Ubuntu(WSL)获取类似Unix版本。
安装完成后,你可以打开终端键入如下命令,确认Python正常工作:python3
, 或者, 只输入 python
。正常情况下,你应该看到回显如下:
$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> _
Python解释器正处于交互模式,等待你输入Python命令进行操作。 接下来的章节你将会看到这个交互界面多有用,但现在,你只是使用它确认一下Python是否能正常工作。 要结束这个交互窗口,你可以输入 exit()
然后回车即可。在 Linux 和Mac OS X 中也可以同时按下 Ctrl-D,而在 Windows上,在你按下 Ctrl-Z 后再按下回车即可。
安装 Flask
下面的内容是如何安装Flask框架,在这之前,我想要告诉你:最好的练习就是安装Python 的packages。(python包,类似于C++的库。一类功能的集合例如Flask)
Python中,类似Flask这样的包都可以从一个公开仓库里面找到,在个公共仓库中所有人都能下载各类包并安装使用。 官方的 Python 包仓库被称为 PyPI,其含义为 Python Package Index (python 包目录有些人称之为 "cheese shop" 奶酪|起司店)。从 PyPI 中安装一个包非常简单,因为Python自带了一个工具pip
,用起来很方便 (在Python 2.7 中 pip
需要单独安装).
在你电脑上启动安装,只需按照下列格式调用 pip
即可:
$ pip install <package-name>
有意思的是,这个安装方法在大部分情况下会出现问题。如果你用全局模式安装的,原因在于你作为普通用户是没有权限进行更改的。因此你必须使用管理员权限的账户才能正确执行此命令。 但如果没啥复杂情况的话,确认一下上面命令执行过程中发生的情况。 pip
工具将从 PyPI 下载软件包,然后将其添加到你的 Python 安装中。 完成这一点后,你系统上的每个 Python 脚本都可以访问此软件包。 设想如下情况,你构建了一个使用Flask0.11版本的web应用(这是当时你开始的时候的最新版本),但现在已经升级到了0.12。你现在希望使用最新的0.12版本构建第二个程序,但如果你直接替换了0.11版,那么你将冒着破坏旧程序的风险。你发觉问题所在了吗?如果能给旧程序按装0.11版Flask,给新程序安装0.12版就非常完美了。
正是处于解决给不同的应用维护不同版本软件包的目的, Python 使用了 virtual environments(虚拟环境)的概念。 每个虚拟环境都是一个独立的Python解释器。当你在虚拟环境中安装软件包时,真实系统下的python环境并不受影响,仅仅虚拟环境下的python受影响。 所以要想给不同程序提供不同的软件环境的解决方法就是使用虚拟环境。 而且虚拟环境还有一个附带的好处就是,无需管理员权限,完全受创建者控制。
我们先创建一个文件夹来存放所有的程序文件。我称之为 microblog, 这也是应用程序的名字:
$ mkdir microblog
$ cd microblog
如果你使用 Python 3 版本,其自带了虚拟环境工具,你可以直接调用:
$ python3 -m venv venv
译注:不同的操作系统下可能会出现差异,目前我使用ubuntu 20.04 ,在运行上述命令时提示未按装venv。需要使用
sudo apt-get iinstall python3-venv
安装一下。
通过此命令,我要求Python运行 venv
软件包,来创建名为 venv
的虚拟环境。 命令行中的第一个 venv
是python软件包venv的名称,第二则是我们在本程序中要用到的虚拟环境的名称。如果你感觉混乱,可以将第二个 venv
替换成你喜欢的名字作为虚拟环境的名称和虚拟程序包的文件存放处。 一般我都喜欢在工程文件夹里创建 venv
,这样无论何时我只要 cd
进入一个工程,就立刻找到对应的虚拟环境。
Note that in some operating systems you may need to use python
instead of python3
in the command above. Some installations use python
for Python 2.x releases and python3
for the 3.x releases, while others map python
to the 3.x releases.
After the command completes, you are going to have a directory named venv where the virtual environment files are stored.
If you are using any version of Python older than 3.4 (and that includes the 2.7 release), virtual environments are not supported natively. For those versions of Python, you need to download and install a third-party tool called virtualenv before you can create virtual environments. Once virtualenv is installed, you can create a virtual environment with the following command:
$ virtualenv venv
不管您使用什么方法创建它, 你应该都创建了一个虚拟环境了。现在你必须告诉系统你要通过 激活 来调用它。 要激活你的全新虚拟环境,你应该使用如下命令:
$ source venv/bin/activate
(venv) $ _
如果你使用微软Windows的命令行提示符窗口,命令会有少许不同:
$ venv\Scripts\activate
(venv) $ _
你在激活一个虚拟环境的时候,你的终端会话配置将会被修改,来确保在你输入python
的时候能找到正确的(虚拟环境中的)Python解释器。同时,终端提示符也会该变成包含被激活的虚拟环境的名字的样子。终端会话的变化都是临时且仅基于当前会话的,所以一旦你关闭当前的终端窗口这些改变就会消失。如果你同时打开多个终端进行操作,那可以在每个终端上激活不同的虚拟环境是非常棒的。
现在,在创建并激活了虚拟环境之后,我们终于可以在其中安装Flask了:
(venv) $ pip install flask
若是想确认一下当前虚拟环境是否安装Flas,你可以启动Python解释器,并 import(导入) Flask包:
>>> import flask
>>> _
如果没有返回错误信息,那么就可以庆贺Flask成功安装并可以使用了。
"Hello, World" Flask 程序
如果你浏览 Flask 官网, 会迎面见到一个只有五行代码的Flask程序。因为不想重复那个简单的例程,我要给你展示一个稍微复杂一些的,且可以继续扩展成一个更大的程序结构。
这个程序将以 package ( 包
)的形式存在。在 Python中, 包含 __init__.py
文件的子文件夹被认为是一个包,可以被导入( import)。 当你导入一个包的时候, init.py 被执行并定义包向外部世界公开哪些元素。
让我们创建一个叫 app
的包,它将包含程序所有东西。确认你目前处在 microblog 文件夹(这是我们工程的顶层文件夹,我们所有的项目文件都处于此文件夹下
)中然后运行如下命令:
(venv) $ mkdir app
app
包的 __init__.py
文件将包含如下代码:
app/__init__.py
: Flask 程序实例
from flask import Flask
app = Flask(__name__)
from app import routes
上面这个脚本通过导入flask包,进而创建了Flask
类的一个程序实例。传递给Flask
类的变量 __name__
是一个 Python 预定义变量,其值被设定为自身所在模块的名称。在需要加载资源(如模板文件等,在第二章会涉及到)的时候,Flask 使用传递来的模块位置作为起始点定位。实际上,传递 __name__
基本上都能正确配置Flask。 程序接着导入 routes
(路由)模块——目前还不存在。
一开始可能有些地方会让人困扰:这里出现了两个实体都被命名为” app
“。 其中app
包是通过 app 文件夹和其中的__init__.py
脚本来定义的,通过from app import routes
声明进行引用。 另外的 app
变量 在__init__.py
脚本中被定义为Flask
类的一个实例,该实例是 app
包的一个成员。
另外一个则是 routes
模块在整个脚本最底部被导入,而其他模块都是在最顶部被导入的。 在底部(最后)导入是为了解决一个Flask程序的常见问题——”循环导入“(circular imports
)。你将会看到,在 routes
模块中,我们还需要导入现在脚本中定义的app
变量,,所以把另外一个反向的导入放到最后,以此避免在这两个文件当中相互导入的错误(为避免互导造成死循环,框架会报错。
)。
那么,在routes
模块中都有什么呢?路由就是程序实现的不同的URLs。在Flask中,处理程序的路由分配被写成Python函数,称之为 view functions 视图函数. 视图函数被映射到一个或多个路由 URLs,这样 Flask 就知道在客户端请求一个给定的URL时执行什么逻辑。
下面是我们第一个视图函数, 保存在 app/routes.py 文件当中:
app/routes.py: 主页路由
from app import app
@app.route('/')
@app.route('/index')
def index():
return "Hello, World!"
这个视图函数相当简洁,只返回一个字符串问候语。函数前面有两行奇怪的代码 @app.route
,它们被称为 decorators(装饰器),属于 Python 语言独有的功能。装饰器修饰紧随其后的函数。装饰器的常见用法是用它来为特定事件注册回调函数。在本例中, @app.route
装饰器把给定的URL作为参数关联给函数。在这个例子,共有两个装饰器,关联了 URLs /
和 /index
给视图函数。这就意味着Web浏览器不论请求这两个URLs的哪一个,Flask都会调用此视图函数并把结果返回给浏览器。 如果你没有完整的体会,当程序运行起来之后就会有点感觉了。
要完成本程序,你还需要有一个Python脚本,放在最高一级目录里(定义Flask实例的那个目录),命名为 microblog.py,内容就是简单的一行代码——导入本Flask程序实例:
microblog.py: 主程序模块
from app import app
还记得那两个都叫 app
的东东吗? 它们俩同时出现在这了。Flask应用实力名为 app
,是 app
包的一个成员(从包中导入一个成员)。 from app import app
语句导入的 app
变量就是包 app
的一个成员。 要是你还觉得困扰,那么你可以把包或者实例变量的名字改一下。(译者 例如:你可以把程序实例名字改成appmember,这样,import后面就得改成appmember了,routes.py中,导入也得改,且装饰器要变成@appmember.route这样子
)
最后只需要确认一下你的操作都正确, 下面的应该是你的整个应用程序结构图:
microblog/
venv/
app/
__init__.py
routes.py
microblog.py
不管你信不信,应用程序的第一版已经完工了。但,在运行之前, Flask 需要知道如何导入本程序,方法就是设置一个 FLASK_APP
环境变量(在microblog文件夹内操作):
(venv) $ export FLASK_APP=microblog.py
你要是使用微软 Windows,应该把上面命令的 export
替换为 set
。
准备好迎接高光时刻了吗?使用下面命令启动程序吧:
(venv) $ flask run
* Serving Flask app "microblog"
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
服务器初始化之后,就会一直等待客户端发起连接。在 flask run
命令之后的输出,表明服务器正运行的服务器IP地址为 127.0.0.1(这个地址其实就是指代你的电脑,这个地址其实还有一个更简单的名字,那就是 localhost)。 web服务器在特定端口号上侦听连接请求——生产环境下的应用程序通常侦听443端口,或者不加密的80端口,但访问这些端口都需要管理员权限。而如果运行在开发模式下,Flask可以自由使用5000端口或其他端口。
现在打开浏览器,在地址栏输入如下URL:
http://localhost:5000/
或者还可以输入:
http://localhost:5000/index
你明白程序的路由映射动作了吗?Do you see the application route mappings in action? 第一个 URL 映射到 /
,而第二个则对应到 /index
。而所有动作都被关联到程序中的同一个视图函数,因此我们看到同样的输出内容——index函数返回的那个欢迎字符串。如果你输入其他的URL,你就会看到一个错误。目前,程序只会识别这两个URL。
如果需要,可以按下Ctrl+C停止运行。
祝贺你!你已经跨出了成为web开发者的第一步,也是最大的一步!
在我结束本章前,我想再提醒一点。由于环境变量不会跨终端会话保存,因此每打开一个终端,你就得设置一次FLASK_APP
环境变量,从1.0版本开始, Flask 允许你注册环境变量,以便于你在运行flask
命令时自动导入。要实现这个选项,你需要安装 python-dotenv 包:
(venv) $ pip install python-dotenv
然后,你就可以把环境变量名称和值写在名为.flaskenv的文件里,把该文件放在工程的最顶层文件夹中:
.flaskenv: 指定flask命令的环境变量
FLASK_APP=microblog.py
这个属于可选项。如果你更喜欢手动设置环境变量,也不错,只要别忘了就行。