基础篇 第一章 初识Flask
前言
这一切开始于2010年4月1日,Armin Ronacher在网上发布了一篇关于“下一代Python微框架”的介绍文章,文章里称这个Denied框架不依赖Python标准库,只需要复制一份deny.py放到你的项目文件夹就可以开始编程。伴随着一本正经的介绍、名人推荐语、示例代码和演示视频,这个“虚假”的项目让不少人都信以为真。5天后,Flask(http://flask.pocoo.org/)就从这么一个愚人节玩笑诞生了。。
1. 初识Flask
Flask是使用Python编写的Web微框架。Web框架可以让我们不用关心底层的请求响应处理,更方便高效地编写Web程序。因为Flask核心简单且易于扩展,所以被称作微框架(micro framework)。Flask有两个主要依赖,一个是WSGI(Web Server Gateway Interface,Web服务器网关接口)工具集——Werkzeug([http://werkzeug.pocoo.org/(http://werkzeug.pocoo.org/)),另一个是Jinja2模板引擎http://jinja.pocoo.org/。Flask只保留了Web开发的核心功能,其他的功能都由外部扩展来实现,比如数据库集成、表单认证、文件上传等。如果没有合适的扩展,你甚至可以自己动手开发。Flask不会替你做决定,也不会限制你的选择。总之,Flask可以变成任何你想要的东西,一切都由你做主
1.1、搭建开发环境
现在我们开始正式的搭建开发环境。
1.1.1 pipenv工作流
Pipenv是基于pip的Python包管理工具,它和pip的用法非常相似,可以看作pip的加强版,它的出现解决了旧的pip+virtualenv+requirements.txt
的工作方式的弊端。具体来说,它是pip、Pipfile和Virtualenv
的结合体,它让包安装、包依赖管理和虚拟环境管理更加方便,使用它可以实现高效的Python项目开发工作流。
sudo pip install pipenv # 全局安装
pip install --user pipenv # 用户安装
具体可参考https://docs.pipenv.org/install/ #installing-pipenv 。
1.1.2 创建虚拟环境
在Python中,虚拟环境(virtual enviroment)
就是隔离的Python解释器环境。通过创建虚拟环境,你可以拥有一个独立的Python解释器环境。
可以通过--three
和--two
选项来声明虚拟环境中使用的Python版本(分别对应Python3和Python2)
,或是使用--python
选项指定具体的版本号。同时要确保对应版本的Python已经安装在电脑中
为当前项目创建一个文件夹,其中包含隔离的Python解释器环境,并且安装pip、wheel、setuptools
等基本的包。
$ pipenv install
Creating a virtualenv for this project…
...
Virtualenv location: /path/to/virtualenv/helloflask-5Pa0ZfZw
...
默认情况下,Pipenv会统一管理所有虚拟环境。在Windows系统中,虚拟环境文件夹会在C:\Users\Administrator\.virtualenvs\
目录下创建,而Linux或macOS会在~/.local/share/virtualenvs/
目录下创建。如果你想在项目目录内创建虚拟环境文件夹,可以设置环境变量PIPENV_VENV_IN_PROJECT
,这时名为.venv
的虚拟环境文件夹将在项目根目录被创建。虚拟环境文件夹的目录名称的形式为“当前项目目录名+一串随机字符”,比如helloflask-5Pa0ZfZw
。
- 显式激活虚拟环境运行
$ pipenv shell
Loading .env environment variables…
Launching subshell in virtual environment. Type 'exit' to return.
(helloflask-5Pa0ZfZw) $
- 无需激活环境运行
$ pipenv run python hello.py
1.1.3 管理环境依赖
requirements.tx
t需要手动维护,在使用上不够灵活。Pipfile
的出现就是为了替代难于管理的requirements.txt。
在创建虚拟环境时,如果项目根目录下没有Pipfile
文件,pipenvinstall
命令还会在项目文件夹根目录下创建Pipfile
和Pipfile.lock
文件,前者用来记录项目依赖包列表,而后者记录了固定版本的详细依赖包列表。当我们使用Pipenv安装/删除/更新依赖包时,Pipfile
以及Pipfile.lock
会自动更新。
安装flask:
$ pipenv install flask
Installing flask...
...
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 click-6.7 flask
备注:
可以使用pipenv graph命令查看当前环境下的依赖情况,或是在
虚拟环境中使用pip list命令查看依赖列表。
**常用命令:**
pipenv --where # 找到项目
pipenv --venv # 找到virtualenv
pipenv --py # 找到Python解释器
pipenv shell # 激活虚拟环境
pipenv graph # 查看当前安装的库和依赖
pipenv uninstall --all # 卸载全部包
高级用法:
pipenv install -r requirements.txt # 将requirments.txt转换为pipfile
pipenv install -r dev-requirements.txt --dev #requirent-dev.txt加入pipfile
#在其他环境建立环境
pipenv install --ignore-pipfile # 生成生产环境, 只需要把代码和Pipfile.lock放到生产环境
pipenv install --dev # 生成开发环境,将代码和Pipfile复制过去
1.1.4 安装Flask
$ pipenv install flask
Installing flask...
...
Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 click-6.7 flask-1.0.2
$ pipenv update flask # 更新flask
1.2 Hello,Flask!
# -*- coding: utf-8 -*-
import click
from flask import Flask
app = Flask(__name__)
# the minimal Flask application
@app.route('/')
def index():
return '<h1>Hello, World!</h1>'
# bind multiple URL for one view function
@app.route('/hi')
@app.route('/hello')
def say_hello():
return '<h1>Hello, Flask!</h1>'
# dynamic route, URL variable default
@app.route('/greet', defaults={'name': 'Programmer'})
@app.route('/greet/<name>')
def greet(name):
return '<h1>Hello, %s!</h1>' % name
# custom flask cli command
@app.cli.command()
def hello():
"""Just say hello."""
click.echo('Hello, Human!')
1.3 启动开发服务器
Flask通过依赖包Click
内置了一个CLI(Command Line Interface,命令行交互界面)
系统。当我们安装Flask后,会自动添加一个flask命令脚本,我们可以通过flask命令执行内置命令、扩展提供的命令或是我们自己定义的命令。其中,flask run
命令用来启动内置的开发服务器:
$ flask run # 已激活虚拟环境
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
备注:
$ pipenv run flask run # 未激活虚拟环境
$ python-m flask run # 遇到command not found 错误
$ flask run --host=192.168.1.1 --port=8000 # 使服务器外部可见,并改变默认端口
Flask的自动发现程序实例机制还有第三条规则:如果安装了python-dotenv
,那么在使用flask run
或其他命令时会使用它自动从.flaskenv
文件和.env
文件中加载环境变量。
当安装了python-dotenv
时,Flask在加载环境变量的优先级是:手动设置的环境变量>.env中设置的环境变量>.flaskenv设置的环境变量
。
为了避免频繁设置环境变量,我们可以使用python-dotenv
管理项目的环境变量,首先使用Pipenv将它安装到虚拟环境:
$ pipenv install python-dotenv
Installing python-dotenv...
Adding python-dotenv to Pipfile's [packages]...
Installation Succeeded
Installing dependencies from Pipfile.lock (a835b0)...
================================ 0/0 - 00:00:00
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
我们在项目根目录下分别创建两个文件:.env和.flaskenv
。.flaskenv
用来存储和Flask相关的公开环境变量,比如FLASK_APP
;而.env
用来存储包含敏感信息的环境变量,比如后面我们会用来配置Email服务器的账户名与密码。在.flaskenv
或.env
文件中,环境变量使用键值对的形式定义,每行一个,以#开头的为注释,如下所示:
SOME_VAR=1
# 这是注释
FOO="BAR"
FLASK_ENV=development
备注:
Flask提供了一个FLASK_ENV
环境变量用来设置环境,默认production
(生产)。在开发时,我们可以将其设为development
(开发),这会开启所有支持开发的特性。为了方便管理,我们将把环境变量FLASK_ENV
的值写入.flaskenv
文件中:
1.4 Flask 扩展
扩展(extension)即使用Flask提供的API接口编写的Python库,可以为Flask程序添加各种各样的功能。以某扩展实现了Foo
功能为例,这个扩展的名称将是Flask-Foo
或Foo-Flask
;程序包或模块的命名使用小写加下划线,即flask_foo
(即导入时的名称);
from flask import Flask
from flask_foo import Foo
app = Flask(__name__)
foo = Foo(app)
1.5 项目配置
在一个项目中,会用到许多配置: Flask提供的配置,扩展提供的
配置,还有程序特定的配置。和平时使用变量不同,这些配置变量都通
过Flask
对象的app.config
属性作为统一的接口来设置和获取,它指向的
Config
类实际上是字典的子类,所以可以像操作其他字典一样操作它。flask配置文档(flask.pocoo.org/docs/latest/config/)
- 可以像在字典中添加一个键值对一样来设置一个配置:
app.config['ADMIN_NAME'] = 'Peter'
- 使用
update()
方法则可以一次加载多个值:
配置的名称必须全大写,小写的变量将不会被读取。
app.config.update(
TESTING=True,
SECRET_KEY='123456'
)
- 读取配置
value = app.config['ADMIN_NAME']
1.6 URL与端点
用Flask提供的url_for()
函数获取URL,当路由中定义的URL规则被修改时,这个函数总会返回正确的URL,增强代码的易用性。
from flask import Flask, url_for
app = Flask(__name__)
@app.route('/login')
def login():
return 'login'
@app.route('/user/<username>')
def profile(username):
return 'hello %s' % username
with app.test_request_context():
print(url_for('login')) # 获取相对url路径
print(url_for('profile', username='JohnDoe')) # 获取带参数相对url路径
print(url_for('profile', username='JohnDoe', _external=True)) # 获取绝对路径
output:
/login
/user/JohnDoe
http://localhost/user/JohnDoe
1.7 Flask 命令
@app.cli.command()
def hello():
click.echo('Hello, Human!')
运行:
$ flask hello
Hello, Human!
1.8 模板与静态文件
模板(template)和静态文件(static file)来生成更加丰富的网页。模板即包含程序页面的HTML文件,静态文件则是需要在HTML文件中加载的CSS和JavaScript文件,以及图片、字体文件等资源文件。默认情况下,模板文件存放在项目根目录中的templates文件夹中,静态文件存放在static文件夹下,这两个文件夹需要和包含程序实例的模块处于同一个目录下,对应的项目结构示例如下所示:
hello/
- templates/
- static/
- app.py
1.9 Flask与MVC架构
MVC架构最初是用来设计桌面程序的,后来也被用于Web程序,应用了这种架构的Web框架有Django、Ruby on Rails等。在MVC架构中,程序被分为三个组件:数据处理(Model)、用户界面(View)、交互逻(Controller)。如果套用MVC架构的内容,那么Flask中视图函数的名称其实并不严谨,使用控制器函数(Controller Function)似乎更合适些,虽然它也附带处理用户界面。严格来说,Flask并不是MVC架构的框架,因为它没有内置数据模型支持。
更多推荐