第1章 初识Flask

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.1Flask 1.0两套环境呢?这时候我们就可以通过虚拟环境来解决这个问题。

1.1.2 虚拟环境原理介绍

虚拟环境相当于一个抽屉,在这个抽屉中安装的任何软件包都不会影响到其他抽屉。并且在项目中,我可以指定这个项目的虚拟环境来配合我的项目。比如我们现在有一个项目是基于Flask 1.1.x版本,又有一个项目是基于Flask 1.0.x的版本,那么这时候就可以创建两个虚拟环境,在这两个虚拟环境中分别安装Flask 1.1.xFlask 1.0.x来适配我们的项目。

1.1.3 安装virtualenv

virtualenv是用来创建虚拟环境的软件工具,我们可以通过pip或者pip3来安装:

pip install virtualenv
pip3 install virtualenv

1. 创建虚拟环境

创建虚拟环境非常简单,通过以下命令就可以创建了:

virtualenv [虚拟环境的名字]

如果你当前的Python3/Scripts的查找路径在Python2/Scripts的前面,那么将会使用python3作为这个虚拟环境的解释器。如果python2/Scriptspython3/Scripts前面,那么将会使用Python2来作为这个虚拟环境的解释器。

2. 进入环境

虚拟环境创建好了以后,那么可以进入到这个虚拟环境中,然后安装一些第三方包,进入虚拟环境在不同的操作系统中有不同的方式,一般分为两种,第一种是Windows,第二种是*nix

  1. windows进入虚拟环境:进入到虚拟环境的Scripts文件夹中,然后执行activate

  2. *nix进入虚拟环境:source /path/to/virtualenv/bin/activate 一旦你进入到了这个虚拟环境中,你安装包,卸载包都是在这个虚拟环境中,不会影响到外面的环境。

3. 退出虚拟环境

退出虚拟环境很简单,通过一个命令就可以完成:deactivate

4. 创建虚拟环境的时候指定Python解释器

在电脑的环境变量中,一般是不会去更改一些环境变量的顺序的。也就是说比如你的Python2/ScriptsPython3/Scripts的前面,那么你不会经常去更改他们的位置。但是这时候我确实是想在创建虚拟环境的时候用Python3这个版本,这时候可以通过-p参数来指定具体的Python解释器:

   virtualenv -p C:\Python36\python.exe [virutalenv name]

1.1.4 virtualenvwrapper

virtualenvwrapper这个软件包可以让我们管理虚拟环境变得更加简单。不用再跑到某个目录下通过virtualenv来创建虚拟环境,并且激活的时候也要跑到具体的目录下去激活。

1. 安装 virtualenvwrapper

  1. *nix下安装:pip install virtualenvwrapper

  2. Windows下安装:pip install virtualenvwrapper-win

2. virtualenvwrapper基本使用

  1. 创建虚拟环境:
  mkvirtualenv my_env

那么会在你当前用户下创建一个Env的文件夹,然后将这个虚拟环境安装到这个目录下。 如果你电脑中安装了python2python3,并且两个版本中都安装了virtualenvwrapper,那么将会使用环境变量中第一个出现的Python版本来作为这个虚拟环境的Python解释器。

  1. 切换到某个虚拟环境:
   workon my_env
  1. 退出当前虚拟环境:
   deactivate
  1. 删除某个虚拟环境:
    rmvirtualenv my_env
  1. 列出所有虚拟环境:
    lsvirtualenv
  1. 进入到虚拟环境所在的目录:
   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详解

URLUniform Resource Locator的简写,统一资源定位符。

一个URL由以下几部分组成:

 scheme://host:port/path/?query-string=xxx#anchor
  • scheme:代表的是访问的协议,一般为http或者https以及ftp等。

  • host:主机名,域名,比如www.baidu.com

  • port:端口号。当你访问一个网站的时候,浏览器默认使用80端口。

  • path:查找路径。比如:www.greatytc.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请求,响应静态文件,常见的有ApacheNginx以及微软的IIS.

  • 应用服务器:负责处理逻辑的服务器。比如phppython的代码,是不能直接通过nginx这种web服务器来处理的,只能通过应用服务器来处理,常见的应用服务器有uwsgitomcat等。

  • web应用框架:一般使用某种语言,封装了常用的web功能的框架就是web应用框架,flaskDjango以及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和相关的依赖(Jinja2Werkzeug)设计得非常优秀,用起来很爽。

  • 开发效率非常高,比如使用SQLAlchemyORM操作数据库可以节省开发者大量书写sql的时间。

  • 社会活跃度非常高。

Flask的灵活度非常之高,他不会帮你做太多的决策,即使做已经帮你做出选择,你也能非常容易的更换成你需要的,比如:

  • 使用Flask开发数据库的时候,具体是使用SQLAlchemy还是MongoEngine或者是不用ORM而直接基于MySQL-Python这样的底层驱动进行开发都是可以的,选择权完全掌握在你自己的手中。区别于DjangoDjango内置了非常完善和丰富的功能,并且如果你想替换成你自己想要的,要么不支持,要么非常麻烦。

  • 把默认的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个依赖包,它们的介绍如图所示:

Flask安装依赖

1.4 第一个Flask程序

用Pycharm新建一个Flask项目,新建项目的截图如下:

img

点击后创建一个新项目,然后在文件中书写代码:

 #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内置命令启动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 runset FLASK_APP命令外还有一些其他命令:

  • set FLASK_ENV:设置运行环境有两个取值development(开发环境)和production(生产环境),默认是生产环境,设置为开发环境会自动开启debug调试
  • flask shell:类似于Python shell,会打开shell命令模式,自动包含flask程序上下文,以及已经导入的app实例
  • flask --help:查看Flask可用的命令及其说明文档
    设置开发环境
    flask shell命令

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_pyfileapp.config.from_objectapp.config.upgrade()app.config[key]=valueapp.config.from_envvar是从虚拟环境中读取配置参数(一般不用):

  1. 使用配置文件,项目里新建一个文件(文件可以是.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,会抛出异常。
  1. 从对象中导入,一般是定义一个配置参数的类(类名可以自定义,一般类名是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)
  1. 可以通过app.config[key]=value,类似于字典的方式直接把相关的配置参数加上。如:
app = Flask(__name__)
app.config['DEBUG'] = True
  1. 通过app.config.upgrade(),因为app.config是字典的一个子类,所以它可以类似字典的方式添加配置参数,可以用字典的upgrade()方法,其实第3和第4种方法本质上是一样的,不过upgrade()方法可以一次性添加多个配置参数
app = Flask(__name__)
app.config.upgrade(DEBUG = True)
  1. 通过环境变量的方式来配置参数,然后通过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可以传参数,比如hostportdebug,如果是配置参数,配置参数只能传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模式

  1. 如果开启了DEBUG模式,那么在代码中如果抛出了异常,在浏览器的页面中可以看到具体的错误信息,以及具体的错误代码位置。方便开发者调试。
  2. 如果开启了DEBUG模式,那么以后在Python代码中修改了任何代码,只要按ctrl+sflask就会自动的重新记载整个网站。不需要手动点击重新运行。

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码。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345