Flask 视图和 URL
1.虚拟环境
为什么需要虚拟环境
到目前为止,我们所有的第三方安装都是直接通过pip install xx 的方式进行安装的,这样安装会将那个包安装到你的系统级的 Python 环境中。但是这样有一个问题,就是如果你出现在用 Django 1.10.x 写了个网站,然后你的领导跟你说,之前有一个旧项目是用 Django 0.9 开发的,让你来维护,但是 Django 1.10 不再兼容 Django 0.9 的一些语法了。这时候就会碰到一个问题,我如何在我的电脑中同时拥有 Django 1.10 和 Django 0.9 两套环境呢? 这时候我们就可以通过虚拟环境来解决这个问题。
pipenv
Windows 安装 pipenv
pip install pipenv # 下载 pipenv
pipenv shell # 进入虚拟环境
exit # 退出虚拟环境
pipenv --rm # 删除整个环境 不会删除 pipfile
设置环境变量
在 PyCharm 中设置
Mac 安装
brew install pipew
Linux 安装
pip install pipenv
pipfile 和 pipfile.lock
pipfile 文件
url # 指定国内pip 源,不然下载库会很慢
dev-packages # 开发环境
packages # 生产环境
django=‘*’ # * 表示最新版本
requires # Python 版本
pipfile.lock,详细记录环境依赖,并且利用了 Hash 算法保证了它完整对应关系
如果需要指定 Python 版本的话,前提是电脑中已经安装了 python2 和 Python3.
pipenv -- three # 泛指Python3 的版本
pipenv -- two # 泛指Python2 的版本
pipenv -- python 3.7 # 指定Python版本
管理开发环境
安装在开发环境下
pipenv install -- dev itchat
在虚拟换将中运行命令,使用run can 参数
pipenv run python mange.py runserver
pipenv 有个缺点 lock 不稳定而且时间非常长,所以安装包的时候记得加上 --skip-lock,最后开发完成要提价到仓库时候在 pipenv lock
pipenv install diango -- skip-lock
2- Flask 简介
Flask 简介
flask 是一款非常流行的 Python Web 框架,出生于 2010,作者是 Aemin Ronacher,本来这个项目只是作者在愚人节的一个玩笑,后来由于非常欢迎,进而成为一个正式的项目。
flask 自2010 年发布第一个版本一以来,大受欢迎,深的开发者的喜爱,并且在多个公司已经得到了应用,flask 能够如此流行的原因,可以分为以下几点:
- 微框架、简洁、只做他需要的,给开发者提供了很大的扩展性。
- Flask 和相应的插件写的很好,用起来很爽。
- 开发效率非常高,比如使用 SQLAIchemy 的 ORM 操作数据库可以节省开发者大量书写 sql 的时间。
Flask 的灵活度非常之高,他不会帮你做太多的决策,一些你都可以按照自己的意愿进行更改。
- 使用 Flask 开发数据库的时候,具体是使用 SQLAIchemy 还是 MongEngine,选择权完全掌握在你自己手中。区别于 Django,Django 内置了非常完善和丰富的功能,并且如果你想替换成你自己想要的,要么不支持,要么非常麻烦。
- 把默认的 Jinija2 模板引擎替换成其他模板引擎都是非常容易的。
第一个 flask 程序
# conding utf8
# 从 flask 框架中导入 Flask 类
from flask import Flask
# 传入 __ name__ 初始化一个 Flask 实例
app=Flask(__name__)
# app.route 装饰器映射 URL 和执行的函数。这个设置将跟 URL 映射到了 hello_world 函数上
@app route('/')
def hello_world():
return 'hello world'
if __name__=='__main__':
# 运行本项目, 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 来让服务停止。
Pycharm 开启 debug 模式和修改 host
在 Pycharm 2018 中,如果想要开启 debug 模式和更改端口号,则需要编辑项目配置。直接在app.run 中更改是无效的。
3. 项目配置
设置为 DEBUG 模式
默认情况下 flask 不会开启 DEBUG 模式,开启 DEBUG 模式后,flask 会在每次保存代码的时候自动的重新载入代码,并且如果代码有错误,会在终端进行显示。
开启DEBUG 模式有四种方式
1.直接在应用对象上设置
app.debug=True
app.run()
2.在执行 run 方式的时候,传递参数进去
app.run(debug=True)
3.在 config 属性中设置
app.config.update(DEBUG=True)
4.通过字典的方式
app.config.update({'DEBUG':True})
如果一切正常,会在终端打印一下信息:
* Debug mode: on
* Restarting with stat
* Debugger is active!
* Debugger PIN: 306-162-897
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
需要注意的是,只能在开发环境下开启 DEBUG 模式,因为 DEBUG 模式会带来非常大的安全隐患。
另外,在开启了 DEBUG 模式后,当程序有异常而进入错误堆栈模式,你第一点击某个堆栈想查看变量值得时候,页面会弹出一个对话框,让你输入 PIN 值,这个 PIN 值在你启动的时候就会出现,比如在刚刚启动的项目中的 PIN 值 为 306-162-897(在自己的终端查看,每个终端的 PIN 不一样),你输入这个值后,Werkzeug 会把这个 PIN 值作为 conkie 的一部分保存起来,并在8小时 过期,8小时以内不需要再输入 PIN 值,这样做的目的是未了更加的安全,让调试模式下的攻击更难攻击道本体。
配置文件
Flask 项目的配置,都是通过app.config 对象来进行配置的,比如一个项目处于 DEBUG 模式下,那么可以使用 app.config[‘DEBUG’]=True 来进行设置,那么 Flask 项目将以 DEBUG 模式运行。在 Flask 项目中,有四种方式进行2项目配置。
- 直接硬编码
app=Flask (__name__)
app.config['DEBUG']=True
2.因为 app.config 是 Flask.config.config 的实例,而 Config类 是继承 dict,因此可以通过 update 方式。
app.config.update(
DEBUG=True,
SECRET_KEY='...'
)
3.如果你的配置项特别多,你可以把所有的配置项都放在一个模块中,然后通过加载模块的方式进行配置,假设有一个 settings.py 模块,专门用来存储配置项的,此时你可以通过app.config.from_object() 方法进行加载,并且该方法既可以接收模块的字符串名称,也可以模块对象。
# 1. 通过模块字符串
app.config.from_object('settings')
# 2.通过模块对象
import settings
app.config.from_object(settings)
4.也可以通过另一个方法加载,该方法就是app.config.from_pyfile(),该方法传入一个文件名,通常是以 .py 结尾的文件,但也不限于只只使用 .py 后缀的文件。
app.config.from_pyfile('settings.py',silent=True)
4. URL与视图
URL与视图
URL 与函数的映射
从之前的 hello world.py 文件中,我们已经看到,一个 URL 要与执行函数进行映射,使用的是 @app.route 装饰器。@app.route 装饰器中,可以指定 URL 的规则来进行更加详细的映射,比如现在要映射一个文章详细的 ULR,文章详细的 URL 是 /article/id/,id 有可能为1、2、3…那么可以通过以下方式。
@app.route('/article/<id>/')
def article(id):
return '%s article detail' % id
其中,尖括号是固定写法,语法为,variable 默认的数据类型是字符串。如果需要指定类型,则需要写成 converter:variable,其中converter 就是类型名称,可以有以下几种。
- string:默认的数据类型,接受没有任何斜杠/的字符串。
- int:整形
- float:浮点型。
- path:和string类似,但是可以传递斜杠/。
- uuid:uuid类型的字符串。
- any:可以指定多种路径。
@app.route('/<any(article,blag):url_path>')
def item(url_path):
return url_path
如果不想定制子路径来传递参数,也可以通过传统的?=的形式来传递参数,例如:/article?id=xxx,这种情况下,可以通过 request.args.get(‘id’)来获取id的值。如果是 post 方法,则可以通过 request.from。get(‘id’)来进行获取。
构造URL(url_for)
一般我们通过一个URL就可以执行到某一个函数。反过来,我们知道一个函数,怎么去获得这个URL呢?url_for 函数就可以帮我们实现这个功能。url_for() 函数接收两个及以上的参数,他接收函数名作为第一个参数,接收对应 URL 规则的命名参数,如果还出现其他的参数,则会添加到 URL 的后面作为查询参数。
通过构建 URL 的方式而选择直接在代码中拼 URL 的原因有两点。
1.将来如果修改了 URL,但没有修改 URL 对应的函数名,就不用到处去替换 URL 了。
2.url_for () 函数会转义一些特殊字符串和 unicode 字符串,这些事情 url_for 会自动的帮我们搞定。
from flask import Flask,url_for
app= Flask(__name__)
@app.route('/article/<id>/')
def article(id):
return '%s article detail' % id
@app.route('/')
def index():
print(url_for('article',id=1))
return '首页'
指定 URL 末尾的斜杠
有些 URL 的末尾是由斜杠的,有些 URL 末尾是没有斜杠的。这其实是两个不同的 URL。
@app.route('/article/')
def articles():
return '文章列表页'
上述例子中,当访问一个结尾不带斜线的 URL:/article,会被重定向到斜线的 URL:/article/上去。但是当我们在定义article的时候,如果在末尾没有加上斜杠,在访问的时候又加上了斜杠,这时候就会抛出一个 404错误页面了:
@app.route('/article')
def articles(request):
return '文章列表页面'
以上没有在末尾加斜杠,因此在访问/article/的时候,就会抛出一个404 错误。
指定 HTTP 方法
在 @app.route() 中可以传入一个关键字参数 methods 来指定本方法支持的 HTTP 方法,默认情况下,只能使用 GET 请求。
@app.route('/login/',methods-['GET','POST'])
def login():
return 'login'
以上装饰器将让 llogin 的 URL 既能支持 GET 又能支持 POST。
页面跳转重重定向
重定向分为永久重定向和暂时性重定向,在页面上体现的操作就是游览器会从一个页面自动跳转到另一个页面。比如用户访问了一个需要权限的页面,但是该用户当前并没有登录,因此我们应该给他重定向到登录页面·。
- 永久性重定向:http 的状态码是 301,多用于旧网址被废弃了要转到一个新的网址确保用户的访问,最经典的就是京网站,你输入www.jingdong.com 的时候,会被重定向到 www.jd.com,因为 jd.com,所以这种情况下应该用永久重定向。
- 暂时性重定向:http 的状态码是 302 ,表示页面的 暂时性跳转。比如访问一个需要权限的网址,如果当前用户没有登录,应该重定向到登录页面,这种情况下,应该用暂时性重定向。
在 flask中,重定向是通过 flask.redirect(location,code=302) 这个函数实现的,location 表示需要重定向到的 URL,应该配合之前讲的 url_for 函数来使用,code 表示采用哪个重定向,默认是 302 也即暂时性重定向,可以修改成 301 来实现永久重定向。
from flask import Flask,url_for,redirect
app=Flask(__name__)
app.debug=True
@app.route('/login/',methods=['GET','POST'])
def login():
return 'login page'
@app.route('/profile',methods=['GET','POST'])
def profile():
name=request.args.get('name')
if not name;
return redirect(url_for('login'))
esle:
return name
关于响应(Response)
视图函数中可以返回以下类型的值:
- Response 对象。
- 字符串。其实 Flask 是根据返回的字符串类型,重新创建一个 werkzeug.wrappers.Response 对象,Response 将该字符串作为主体,状态码为 200,MIMI 类型为 text/html,然后返回该 Response 对象。
- 如果不是以上三种类型。那么 Flask 会通过 Response.force_type(rv,request.environ)转换为一个请求对象。
直接使用 Response 创建
from werkzeug.wrappers import Response
@app.route('/about/')
def about():
resp=Rseponse(response='about page',status=200,content_type='text/html;charset=utf-8')
return resp
可以 使用 make_response 函数来创建 Response 对象,这个方法可以设置额外的数据,比如设置 cokie,header 信息
from flask import make_response
@app.route('/about')
def about():
return make_response('about page')
通过返回元组的形式
@app.errorhandler(404)
def not_found():
return 'not found',404