1.1 虚拟环境
1.1.1 为什么需要虚拟环境
学习Flask
之前,我们所有的第三方包安装都是直接通过pip install xx
的方式进行安装的,这样安装会将那个包安装到你的系统级的Python
环境中。但是这样有一个问题,就是如果你现在用Flask 1.1.x
写了个网站,然后你的领导跟你说,之前有一个旧项目是用Flask 1.0.x
开发的,让你来维护,但是Flask 1.1
不再兼容Flask 1.0
的一些语法了。这时候就会碰到一个问题,我如何在我的电脑中同时拥有Flask 1.1
和Flask 1.0
两套环境呢?这时候我们就可以通过虚拟环境来解决这个问题。
1.1.2 虚拟环境原理介绍
虚拟环境相当于一个抽屉,在这个抽屉中安装的任何软件包都不会影响到其他抽屉。并且在项目中,我可以指定这个项目的虚拟环境来配合我的项目。比如我们现在有一个项目是基于Flask 1.1.x
版本,又有一个项目是基于Flask 1.0.x
的版本,那么这时候就可以创建两个虚拟环境,在这两个虚拟环境中分别安装Flask 1.1.x
和Flask 1.0.x
来适配我们的项目。
1.1.3 安装virtualenv
virtualenv
是用来创建虚拟环境的软件工具,我们可以通过pip
或者pip3
来安装:
pip install virtualenv
pip3 install virtualenv
1. 创建虚拟环境
创建虚拟环境非常简单,通过以下命令就可以创建了:
virtualenv [虚拟环境的名字]
如果你当前的Python3/Scripts
的查找路径在Python2/Scripts
的前面,那么将会使用python3
作为这个虚拟环境的解释器。如果python2/Scripts
在python3/Scripts
前面,那么将会使用Python2
来作为这个虚拟环境的解释器。
2. 进入环境
虚拟环境创建好了以后,那么可以进入到这个虚拟环境中,然后安装一些第三方包,进入虚拟环境在不同的操作系统中有不同的方式,一般分为两种,第一种是Windows
,第二种是*nix
:
windows
进入虚拟环境:进入到虚拟环境的Scripts
文件夹中,然后执行activate
。*nix
进入虚拟环境:source /path/to/virtualenv/bin/activate
一旦你进入到了这个虚拟环境中,你安装包,卸载包都是在这个虚拟环境中,不会影响到外面的环境。
3. 退出虚拟环境
退出虚拟环境很简单,通过一个命令就可以完成:deactivate
。
4. 创建虚拟环境的时候指定Python解释器
在电脑的环境变量中,一般是不会去更改一些环境变量的顺序的。也就是说比如你的Python2/Scripts
在Python3/Scripts
的前面,那么你不会经常去更改他们的位置。但是这时候我确实是想在创建虚拟环境的时候用Python3
这个版本,这时候可以通过-p
参数来指定具体的Python
解释器:
virtualenv -p C:\Python36\python.exe [virutalenv name]
1.1.4 virtualenvwrapper
virtualenvwrapper
这个软件包可以让我们管理虚拟环境变得更加简单。不用再跑到某个目录下通过virtualenv
来创建虚拟环境,并且激活的时候也要跑到具体的目录下去激活。
1. 安装 virtualenvwrapper
*nix
下安装:pip install virtualenvwrapper
Windows
下安装:pip install virtualenvwrapper-win
2. virtualenvwrapper基本使用
- 创建虚拟环境:
mkvirtualenv my_env
那么会在你当前用户下创建一个Env
的文件夹,然后将这个虚拟环境安装到这个目录下。 如果你电脑中安装了python2
和python3
,并且两个版本中都安装了virtualenvwrapper
,那么将会使用环境变量中第一个出现的Python
版本来作为这个虚拟环境的Python
解释器。
- 切换到某个虚拟环境:
workon my_env
- 退出当前虚拟环境:
deactivate
- 删除某个虚拟环境:
rmvirtualenv my_env
- 列出所有虚拟环境:
lsvirtualenv
- 进入到虚拟环境所在的目录:
cdvirtualenv
3. 修改mkvirtualenv的默认路径
在我的电脑->右键->属性->高级系统设置->环境变量->系统变量
中添加一个参数WORKON_HOME
,将这个参数的值设置为你需要的路径。
4. 创建虚拟环境的时候指定Python版本
在使用mkvirtualenv
的时候,可以指定--python
的参数来指定具体的python
路径:
mkvirtualenv --python==C:\Python36\python.exe my_env
1.2 认识web
1.2.1 url详解
URL
是Uniform Resource Locator
的简写,统一资源定位符。
一个URL
由以下几部分组成:
scheme://host:port/path/?query-string=xxx#anchor
scheme:代表的是访问的协议,一般为
http
或者https
以及ftp
等。host:主机名,域名,比如
www.baidu.com
。port:端口号。当你访问一个网站的时候,浏览器默认使用80端口。
path:查找路径。比如:
www.jianshu.com/trending/now
,后面的trending/now
就是path
。query-string:查询字符串,比如:
www.baidu.com/s?wd=python
,后面的wd=python
就是查询字符串。anchor:锚点,后台一般不用管,前端用来做页面定位的。
注意:URL
中的所有字符都是ASCII
字符集,如果出现非ASCII
字符,比如中文,浏览器会进行编码再进行传输。
1.2.2 web服务器和应用服务器以及web应用框架
web服务器:负责处理
http
请求,响应静态文件,常见的有Apache
,Nginx
以及微软的IIS
.应用服务器:负责处理逻辑的服务器。比如
php
、python
的代码,是不能直接通过nginx
这种web服务器来处理的,只能通过应用服务器来处理,常见的应用服务器有uwsgi
、tomcat
等。web应用框架:一般使用某种语言,封装了常用的
web
功能的框架就是web应用框架,flask
、Django
以及Java中的SSH(Structs2+Spring3+Hibernate3)
框架都是web应用框架。
1.2.3 Content-type和Mime-type的作用和区别
两者都是指定服务器和客户端之间传输数据的类型,区别如下:
- Content-type:既可以指定传输数据的类型,也可以指定数据的编码类型,例如:
text/html;charset=utf-8
- Mime-type:不能指定传输的数据编码类型。例如:
text/html
常用的数据类型如下:
text/html
(默认的,html文件)text/plain
(纯文本)text/css
(css文件)text/javascript
(js文件)application/x-www-form-urlencoded
(普通的表单提交)multipart/form-data
(文件提交)application/json
(json传输)application/xml
(xml文件)
1.3 Flask简介
Flask
是一款非常流行的Python Web
框架,出生于2010年,作者是Armin Ronacher
,本来这个项目只是作者在愚人节的一个玩笑,后来由于非常受欢迎,进而成为一个正式的项目。目前为止最新的版本是1.1.2
。
Flask
自2010年发布第一个版本以来,大受欢迎,深得开发者的喜爱,并且在多个公司已经得到了应用,Flask
能如此流行的原因,可以分为以下几点:
微框架、简洁、只做他需要做的,给开发者提供了很大的扩展性。
Flask
和相关的依赖(Jinja2
、Werkzeug
)设计得非常优秀,用起来很爽。开发效率非常高,比如使用
SQLAlchemy
的ORM
操作数据库可以节省开发者大量书写sql
的时间。社会活跃度非常高。
Flask
的灵活度非常之高,他不会帮你做太多的决策,即使做已经帮你做出选择,你也能非常容易的更换成你需要的,比如:
使用
Flask
开发数据库的时候,具体是使用SQLAlchemy
还是MongoEngine
或者是不用ORM
而直接基于MySQL-Python
这样的底层驱动进行开发都是可以的,选择权完全掌握在你自己的手中。区别于Django
,Django
内置了非常完善和丰富的功能,并且如果你想替换成你自己想要的,要么不支持,要么非常麻烦。把默认的
Jinija2
模板引擎替换成Mako
引擎或者是其他模板引擎都是非常容易的。
1.3.1 flask文档
中文文档: https://dormousehole.readthedocs.io/en/latest/
英文文档: https://flask.palletsprojects.com/en/1.1.x/
1.3.2 安装Flask
我们可以通过pip
或者pip3
来安装Flask
:
# Python2或者Python3安装方式
pip install flask
# Python3安装方式
pip3 install flask
执行上面命令后,除了安装Flask
包外,同时被安装的还有5个依赖包,它们的介绍如图所示:
1.4 第一个Flask程序
用Pycharm新建一个Flask项目,新建项目的截图如下:
点击后创建一个新项目,然后在文件中书写代码:
#coding: utf8
# 从flask这个包中导入Flask这个类
# Flask这个类是项目的核心,以后很多操作都是基于这个类的对象
# 注册url、注册蓝图等都是基于这个类的对象
from flask import Flask
# 创建一个Flask对象,传递__name__参数进去
# __name__参数的作用:
# 1. 可以规定模版和静态文件的查找路径
# 2. 以后一些Flask插件,比如Flask-migrate、Flask-SQLAlchemy如果报错了,那么Flask
# 可以通过这个参数找到具体的错误位置
app = Flask(__name__)
# app.route装饰器映射URL和执行的函数。这个设置将根URL映射到了hello_world函数上
# @app.route:是一个装饰器
# @app.route('/')就是将url中的/映射到hello_world这个视图函数上面
# 以后你访问我这个网站的/目录的时候,会执行hello_world这个函数,然后将这个函数的返回值
# 返回给浏览器。
# wwww.baidu.com/ -> hello_world函数
@app.route('/')
def hello_world():
return 'Hello World!'
# 如果这个文件是作为一个主文件运行,那么就执行app.run()方法
# 也就是启动这个网站
if __name__ == '__main__':
# app.run()
# 运行本项目,host=0.0.0.0可以让其他电脑也能访问到该网站,port指定访问的端口。默认的host是127.0.0.1,port为5000
app.run(host='0.0.0.0',port=9000)
然后点击运行,在浏览器中输入 http://127.0.0.1:9000
就能看到hello world
了。需要说明一点的是,app.run
这种方式只适合于开发,如果在生产环境中,应该使用Gunicorn
或者uWSGI
来启动。如果是在终端运行的,可以按ctrl+c
来让服务停止。
1.4.1 用Flask内置命令行的方式启动Flask
上面例子是通过Pycharm
点击运行来启动Flask或者使用cmd
来启动Flask
(cmd
进入项目目录然后输入python app.py
),其实Flask通过依赖包Click
内置了一个CLI
,我们可以执行Flask
内置的命令来启动Flask
:
flask run
命令还可以指定主机和端口,只需要在后面加上
--host=0.0.0.0 --port=8000
,这两个配置可以指定其中任意一个也可以两个同时指定:
需要注意的是因为我们的主模块名为
app.py
,所以
flask run
命令会自动寻找程序实例,如果我们的主程序模块是其他名称,比如
hello.py
,那么需要设置环境变量
FLASK_APP
,否则运行
flask run
将找不到主模块,不能启动
Flask
服务。
# Linux或macOS系统设置FLASK_APP
$ export FLASK_APP=hello
# Windows系统设置FLASK_APP
> set FLASK_APP=hello
1.4.2 Flask依赖包Click内置的其他命令
Flask除了内置flask run
和set FLASK_APP
命令外还有一些其他命令:
-
set FLASK_ENV
:设置运行环境有两个取值development
(开发环境)和production
(生产环境),默认是生产环境,设置为开发环境会自动开启debug调试
-
flask shell
:类似于Python shell
,会打开shell
命令模式,自动包含flask程序上下文
,以及已经导入的app实例
-
flask --help
:查看Flask
可用的命令及其说明文档
1.4.3 自定义Flask命令
除了Flask
内置的命令,我们还可以自定义命令,自定义命令分以下几步:
- 建立任意一个函数
- 为所建函数添加
app.cli.command()
装饰器,装饰器里可以添加参数,这个参数会作为运行时的命令名称,不添加参数,默认使用自定义的函数名称为命令名称 - 然后在CLI下运行
flask 自定义函数名
例如我们自定义一个hello()
命令函数,我们运行自定义命令时会在CLI
中输出hello world!
import click
# 可以在装饰器里添加参数,这个参数会作为运行时的命令名称
# 如@app.cli.command('say-hello'),运行时输入 flask say-hello
@app.cli.command()
def hello():
# click模块的echo()函数可以在命令界面输出字符
click.echo('hello world!')
1.5 app初始化参数
app = Flask()
的可选参数:
import_name
: 导入路径(寻找静态目录与模板目录位置的参数),一般写__name__
。
static_url_path
:访问静态资源的前缀,默认static
,这个前缀目录下都是静态资源。
static_folder
: 静态目录的名字,默认static
,其实就是项目中项目目录存放静态资源文件夹的名字。
template_folder
: 模板目录的名字,默认templates
, 其实就是项目中项目目录存放模板文件文件夹的名字。
from flask import Flask
app = Flask(__name__,static_url_path='data',static_folder="front",template_folder="html_source" )
"""
这样定义后,我们在浏览器访问静态资源就不能使用默认的前缀static(http://127.0.0.1:5000/static/01.jpg),
需要加上data前缀,http://127.0.0.1:5000/data/01.jpg,而且我们项目目录中存放静态资源的文件夹的名字
就不能是默认的static而要用定义了的front,最后我们项目目录中存放模板的文件夹的名字就不能是默认templates,
而要使用定义的html_source
"""
1.6 配置参数
有5种方式来设置Flask
的配置参数,使用app.config.from_pyfile
和app.config.from_object
,app.config.upgrade()
,app.config[key]=value
,app.config.from_envvar
是从虚拟环境中读取配置参数(一般不用):
- 使用配置文件,项目里新建一个文件(文件可以是
.py文件
或者.txt文件
等),把相关的配置写到该文件中然后通过app
对象的config
属性的from_pyfile
方式来导入配置文件。如在项目目录中定义配置文件为"config.cfg"
,在程序中引入配置文件方式:app.config.from_pyfile("config.cfg")
,路径可以是相对路径或者绝对路径,这种方式,可以传递silent=True
,那么这个静态文件没有找到的时候,不会抛出异常,我们在文件中定义的配置参数也不会生效。
app.config.from_pyfile('config.cfg',silent=True)
# silent=True表示如果配置文件不存在的时候不抛出异常,默认是为False,会抛出异常。
- 从对象中导入,一般是定义一个配置参数的类(类名可以自定义,一般类名是
Config
),再把相关的参数配置以类属性的方式定义,然后通过app
对象的config
属性的from_ object
方式来导入。如定义一个Config
类:
class Config(object):
DEBUG = True
# 导入方式
app.config.from_object(Config)
导入方式:app.config.from_object(Config)
,可以不用实例化一个Config
对象,因为类也是对象,flask
会自动从Config
类中读取参数
也可以在项目目录里定义一个.py文件
,然后在主app文件中导入,再使用app.config.from_object()
的方式来配置,这种方式和使用app.config.from_pyfile()
不同在于需要导入.py文件
,而且app.config.from_pyfile()
方式不要导入但是需要指定配置文件位置及其文件后缀
# 导入项目目录里定义的config.py文件
import config
# 配置config
app.config.from_object(config)
- 可以通过
app.config[key]=value
,类似于字典的方式直接把相关的配置参数加上。如:
app = Flask(__name__)
app.config['DEBUG'] = True
- 通过
app.config.upgrade()
,因为app.config
是字典的一个子类,所以它可以类似字典的方式添加配置参数,可以用字典的upgrade()
方法,其实第3和第4种方法本质上是一样的,不过upgrade()
方法可以一次性添加多个配置参数
app = Flask(__name__)
app.config.upgrade(DEBUG = True)
- 通过环境变量的方式来配置参数,然后通过
app.config.from_envvar()
来读取配置参数
# 在环境变量中设置MyAppConfig,并在其中设置配置参数
app.config.from_envvar('MyAppConfig')
1.6.1 在视图读取配置参数
如果我们需要指定一个配置参数它的值是什么,我们有2种方法:
-
app.config.get()
按照字典取值的方法获取配置参数的值或者是先导入current_app
再用current_app.config.get()
按照字典取值的方法获取配置参数的值,如果没有定义该配置参数将返回None
-
app.config[key]
按照字典取值的方式来获取配置参数,如果没有定义该配置参数将返回None
1.6.2 app.run的参数
启动app可以传参数,比如host
、port
,debug
,如果是配置参数,配置参数只能传debug
,如果想在同一个局域网下的其他电脑访问自己电脑上的Flask
网站,那么可以在app.run()
中设置host='0.0.0.0'
才能访问得到
app.run(host="0.0.0.0", port=5000,debug=True)
1.7 开启debug模式
1.7.1 为什么需要开启DEBUG模式
- 如果开启了
DEBUG
模式,那么在代码中如果抛出了异常,在浏览器的页面中可以看到具体的错误信息,以及具体的错误代码位置。方便开发者调试。 - 如果开启了
DEBUG
模式,那么以后在Python
代码中修改了任何代码,只要按ctrl+s
,flask
就会自动的重新记载整个网站。不需要手动点击重新运行。
1.7.2 debug配置的7种方式
debug
配置的其中5种方式其实就是上面说的如何导入配置参数的那5种方式,还有两种方式也讲到了,就是在命令行使用set FLASK_ENV=development
,然后再使用flask run
会自动启用debug模式
,不过这种配置仅限于flask run
启动,还有一种配置方式就是app.run(debug=True)
在Pycharm中有些配置方式是没有效果
1.7.3 PIN码
开启了debug
模式后,flask会自动生成一个PIN
码,PIN
码用于页面调试如果想要在网页上调试代码,那么应该输入PIN
码。