Flask框架——(认识Flask框架及项目配置)
1. Flask框架介绍
flask是⼀款⾮常流⾏的Python Web框架,出⽣于2010年,作者是ArminRonacher,本来这个项⽬只是作者在愚⼈节的⼀个玩笑,后来由于⾮常受欢迎,进⽽成为⼀个正式的项⽬。
flask⾃2010年发布第⼀个版本以来,⼤受欢迎,深得开发者的喜爱,并且在多个公司已经得到了应⽤,flask能如此流⾏的原因,可以分为以下⼏点:
- 微框架、简洁、只做他需要做的,给开发者提供了很⼤的扩展性。
- Flask和相应的插件写得很好,⽤起来很爽。
- 开发效率⾮常⾼,⽐如使⽤SQLAlchemy的ORM操作数据库可以节省开发者⼤量书写sql的时间
Flask的灵活度⾮常之⾼,他不会帮你做太多的决策,⼀些你都可以按照⾃⼰的
意愿进⾏更改。
- 使⽤Flask开发数据库的时候,具体是使⽤SQLAlchemy还是MongoEngine,选择权完全掌握在你⾃⼰的⼿中。区别于Django,Django内置了⾮常完善和丰富的功能,并且如果你想替换成你⾃⼰想要的,要么不⽀持,要么⾮常麻烦。
- 把默认的Jinija2模板引擎替换成其他模板引擎都是⾮常容易的。
Flask目录介绍:
2. 第一个Flask程序
# 从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来让服务停⽌。
3. 项目配置
3-1. 设置为DEBUG模式
为什么要设置DEBUG模式?
- 当代码有错时,会直接出现在html上,方便开发人员发现错误
- 开启debug模式后,flask会在每次保存代码的时候自动的重新载入代码
- flask默认未开启debug模式
注意: 只能在开发环境下开启DEBUG模式,因为DEBUG模式会带来⾮常⼤的安全隐患。
在开启了DEBUG模式后,当程序有异常⽽进⼊错误堆栈模式,你第⼀次点击某个堆栈想查看变量值的时候,⻚⾯会弹出⼀个对话框,让你输⼊PIN值,这个PIN值在你启动的时候就会出现,⽐如在刚刚启动的项⽬中的PIN值为294-745-044,你输⼊这个值后,Werkzeug会把这个PIN值作为cookie的⼀部分保存起来,并在8⼩时候过期,8⼩时以内不需要再输⼊PIN值。这样做的⽬的是为了更加的安全,让调试模式下的攻击者更难攻击到本站。
3-2. 开启DEBUG模式的四种方式
3-2-1. 直接在应用对象上设置
代码示例:
app.debug = True
app.run()
3-2-2. 在执行run方法的时候,传递参数进去
代码示例:
app.run(debug=True)
3-2-3. 在config属性中设置
代码示例:
app.config.update(DEBUG=True)
如果一切正常,会在终端打印以下信息:
* Restarting with stat
* Debugger is active!
* Debugger pin code: 294-745-044
* Running on http://0.0.0.0:9000/ (Press CTRL+C to quit)
3-2-4. 在Pycharm专业版设置
在Pycharm专业版中(社区版不用),在app.run()
中更改是无效的,需要编辑项目配置。
3-3. 配置文件
介绍: Flask项⽬的配置,都是通过app.config对象来进⾏配置的。⽐如要配置⼀个项⽬处于DEBUG模式下,那么可以使⽤app.config['DEBUG] = True来进⾏设置,那么Flask项⽬将以DEBUG模式运⾏。在Flask项⽬中,有四种⽅式进⾏项⽬的配置。
3-3-1. 硬编码方式
代码示例:
app = Flask(__name__)
app.config['DEBUG'] = True
3-3-2. 通过update
方法
因为app.config是flask.config.Config的实例,⽽Config类是继承⾃dict,所有可以用update
方法。
代码示例:
app.config.update(
DEBUG=True,
SECRET_KEY='...'
)
3-3-3. 通过app.config.from_object()
方法加载自定义模块
如果你的配置项特别多,你可以把所有的配置项都放在⼀个模块中,然后通过加载模块的⽅式进⾏配置,假设有⼀个settings.py
模块,专⻔⽤来存储配置项的,此时你可以通过app.config.from_object()
⽅法进⾏加载,并且该⽅法既可以接收模块的的字符串名称,也可以模块对象。
代码示例:
# 1. 通过模块字符串
app.config.from_object('settings')
# 2. 通过模块对象
import settings
app.config.from_object(settings)
3-3-4. 通过app.config.from_pyfile()
加载自定义模块
该⽅法传⼊⼀个⽂件名,通常是以.py
结尾的⽂件,但也不限于只使⽤.py
后缀的⽂件。
代码示例:
app.config.from_pyfile('settings.py',silent=True)
4. URL与视图
4-1. URL与函数的映射
介绍: 从之前的helloworld.py⽂件中,我们已经看到,⼀个URL要与执⾏函数进⾏映射,使⽤的是@app.route
装饰器。@app.route
装饰器中,可以指定URL的规则来进⾏更加详细的映射,⽐如现在要映射⼀个⽂章详情的URL,⽂章详情的URL是/article/id/
,id有可能为1、2、3…,那么可以通过以下⽅式。
- string: 默认的数据类型,接受没有任何斜杠/的字符串。
- int: 整形。
- float: 浮点型。
- path: 和string类似,但是可以传递斜杠
/
。 - uuid: uuid类型的字符串。
- any:可以指定多种路径
- 代码示例:
@app.route('/<any(article,blog):url_path>/')
def item(url_path):
return url_path
如果不想定制⼦路径来传递参数,也可以通过传统的?=的形式来传递参数,例如:/article?id=xxx,这种情况下,可以通过request.args.get('id')
来获取id的值。如果是post⽅法,则可以通过request.form.get('id')
来进⾏获取。
4-2. 构造URL
介绍: ⼀般我们通过⼀个URL就可以执⾏到某⼀个函数。如果反过来,我们知道⼀个函数,怎么去获得这个URL呢?url_for函数就可以帮我们实现这个功能。url_for()函数接收两个及以上的参数,他接收函数名作为第⼀个参数,接收对应URL规则的命名参数,如果还出现其他的参数,则会添加到URL的后⾯作为查询参数。
url_for(函数名)
的优势:
- 如果只修改了URL,但没有修改该URL对应的函数名,就不⽤到处去替换URL了。
-
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 "⾸⻚"
4-3. 指定URL末尾的斜杠
有些URL的末尾是有斜杠的,有些URL末尾是没有斜杠的。这其实是两个不同的URL。
@app.route('/article/')
def articles():
return '⽂章列表⻚'
上述例⼦中,当访问⼀个结尾不带斜线的URL:/article,会被重定向到带斜线的URL:/article/上去。但是当我们在定义article的url的时候,如果在末尾没有加上斜杠,但是在访问的时候⼜加上了斜杠,这时候就会抛出⼀个404错误⻚⾯了:
@app.route("/article")
def articles(request):
return "⽂章列表⻚⾯"
以上没有在末尾加斜杠,因此在访问/article/的时候,就会抛出⼀个404错误。
4-4. 指定HTTP⽅法
在@app.route()
中可以传⼊⼀个关键字参数methods来指定本⽅法⽀持的HTTP⽅法,默认情况下,只能使⽤GET请求。
代码示例:
@app.route('/login/',methods=['GET','POST'])
def login():
return 'login'
注意: 当指定了methods
时,只有指定的方法有效,默认的GET将失效,可以同时指定多个请求方法。
4-5. 页面跳转和重定向
介绍: 重定向分为永久性重定向和暂时性重定向,在⻚⾯上体现的操作就是浏览器会从⼀个⻚⾯⾃动跳转到另外⼀个⻚⾯。⽐如⽤户访问了⼀个需要权限的⻚⾯,但是该⽤户当前并没有登录,因此我们应该给他重定向到登录⻚⾯。
- 永久性重定向:
301
,多⽤于旧⽹址被废弃了要转到⼀个新的
⽹址确保⽤户的访问,最经典的就是京东⽹站,你输⼊www.jingdong.com的时候,会被重定向到www.jd.com,因为jingdong.com这个⽹址已经被废弃了,被改成jd.com,所以这种情况下应该⽤永久重定向。 - 暂时性重定向:
302
,表示⻚⾯的暂时性跳转。⽐如访问⼀个
需要权限的⽹址,如果当前⽤户没有登录,应该重定向到登录⻚⾯,这种情况下,应该⽤暂时性重定向。
Flask中,如何指定重定向?
在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'))
else:
return name
4-6. 响应(Response
)
可以返回的值:
- Response对象。
- 字符串。其实Flask是根据返回的字符串类型,重新创建⼀个
werkzeug.wrappers.Response
对象,Response将该字符串作为主体,状态码为200,MIME类型为text/html,然后返回该Response对象。 - 元组。元组中格式是(response,status,headers)。response为⼀个字符串,status值是状态码,headers是⼀些响应头。
- 如果不是以上三种类型。那么Flask会通过
Response.force_type(rv,request.environ)
转换为⼀个请求对象。
代码示例1:直接使用Response创建
# 需要额外导入Rexponse
from werkzeug.wrappers import Response
@app.route('/about/')
def about():
resp = Response(response='about page',status=200,content_type='text/html;c
harset=utf-8')
return resp
代码示例2:make_response
函数创建
# 需要额外导入make_response
from flask import make_response
@app.route('/about/')
def about():
return make_response('about page')
代码示例3:返回元组的形式
@app.errorhandler(404)
def not_found():
return 'not found',404