Flask框架
为什么要学习Flask?
- Flask自由、灵活,可扩展性强,第三方库的选择面广,开发时可以结合自己最喜欢用的轮子,也能结合最流行最强大的Python库
- 入门简单,即便没有多少web开发经验,也能很快做出网站
- 非常适用于小型网站
- 非常适用于开发web服务的API
- 开发大型网站无压力,但代码架构需要自己设计,开发成本取决于开发者的能力和经验
- 各方面性能均等于或优于Django
Django自带的或第三方的好评如潮的功能,Flask上总会找到与之类似第三方库
Flask灵活开发,Python高手基本都会喜欢Flask,但对Django却可能褒贬不一 - Flask与关系型数据库的配合使用不弱于Django,而其与NoSQL数据库的配合远远优于Django
- Flask比Django更加Pythonic,与Python的philosophy更加吻合
简介
Flask诞生于2010年,是Armin ronacher(人名)用Python语言基于Werkzeug工具箱编写的轻量级Web开发框架。它主要面向需求简单的小应用。
Flask本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login),都需要用第三方的扩展来实现。比如可以用Flask-extension加入ORM、窗体验证工具,文件上传、身份验证等。Flask没有默认使用的数据库,你可以选择MySQL,也可以用NoSQL。其 WSGI 工具箱采用 Werkzeug(路由模块) ,模板引擎则使用 Jinja2 。
可以说Flask框架的核心就是Werkzeug和Jinja2。
Python最出名的框架要数Django,此外还有Flask、Tornado等框架。虽然Flask不是最出名的框架,但是Flask应该算是最灵活的框架之一,这也是Flask受到广大开发者喜爱的原因。
Flask的Github地址:https://github.com/pallets/flask
Flask中文文档地址:http://docs.jinkan.org/docs/flask/
Flask入门程序示例(从Hello World开始)
为加快开发效率,我们使用Pycharm的professional版本进行创建flask程序
选择Flask框架然后指定工程的位置和python解释器环境,模板引擎选择Jinjia2模板的文件夹选择默认的templates文件夹
创建完之后,会自动生成相应的配置文件,运行app.run()
在浏览器中输入http://127.0.0.1:5000/
Flask目录结构
下图是flask项目的参考目录结构
由上图我们可以看出,pycharm为我们自动创建了static和templates两个文件夹,如有其他需求还要我们自行创建,static文件主要是存放静态文件,templates存放Jinjia2模板文件
接下来我们重点关注app.py文件
# 导入Flask类
from flask import Flask
#Flask类接收一个参数__name__
# __name__表示当前模块的名字
#模块名传入的意义
#flask以这个模块所在的目录为总目录
# 默认这个目录中的static文件夹为静态文件目录
# templates为 模板目录
import demo
app = Flask(__name__)
# 装饰器的作用是将路由映射到视图函数index
@app.route('/')
def index():
"""定义视图视图函数"""
return 'Hello World!'
# Flask应用程序实例的run方法启动WEB服务器
# 如果当前模块作为启动模块, __name__ 就是 __main__
# 如果是导入这个模块当做包被导入,__name__ 是文件的名字
if __name__ == '__main__':
app.run()
静态文件访问
在static文件夹下新建index.html,并且添加h1标题内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Welcome to Flask World</h1>
</body>
</html>
然后我们访问http://127.0.0.1:5000/static/index.html就可以看到相应的效果
如果说我们更改 app = Flask("dsadsadas") 这样的任意的字符串,按理来说Flask会去找dsadsadas这个模块所在目录为总目录,但是实际上并没有这个模块,所以flask找不到,找不到flask会默认当前这个启动文件所在的目录为总目录,总目录下的static文件夹为静态文件目录,所以访问http://127.0.0.1:5000/static/index.html仍然可以成功(注意如果测试字符串是abc,则找不到,因为标准库里有abc模块)
路由参数设置
我们使用app.url_map查看所有路由,下面演示一些路由设置,此外还有动态路由和定义请求方式路由
from flask import Flask
app = Flask(__name__)
# 路由
@app.route('/hello')
def index():
"""定义视图视图函数"""
return 'hello'
# 同一视图函数对应多个装饰器都可以访问该视图函数
@app.route('/hi1')
@app.route('/hi2')
def hi():
return 'hi i am here!'
# 查看所有路由
print(app.url_map)
if __name__ == '__main__':
app.run()
Jinja2模板引擎
使用Flask的render_template渲染模板
在app.py中修改如下代码
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/index')
def index():
# 第一个参数数模板的名字,第二个参数是返回值,平铺的方式即可
return render_template("index.html", name='鲁班七号', grade=15)
# 2. Django 一般都是传入的字典,如果用类似方式可以这样
# **data 代表解包的意思
data = {
"name": "安琪拉",
"grade": 13
}
return render_template("index.html", **data)
if __name__ == '__main__':
app.run()
在templates目录下新建index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>英雄:</h1>
<p>{{ name }}</p>
<h1>等级:</h1>
<p>{{ grade }}</p>
</body>
</html>
Flask过滤器
safe:禁用转义;
<p>{{ '<em>hello</em>' | safe }}</p>
capitalize:把变量值的首字母转成大写,其余字母转小写;
<p>{{ 'hello' | capitalize }}</p>
lower:把值转成小写;
<p>{{ 'HELLO' | lower }}</p>
upper:把值转成大写;
<p>{{ 'hello' | upper }}</p>
title:把值中的每个单词的首字母都转成大写;
<p>{{ 'hello' | title }}</p>
trim:把值的首尾空格去掉;
<p>{{ ' hello world ' | trim }}</p>
reverse:字符串反转;
<p>{{ 'olleh' | reverse }}</p>
format:格式化输出;
<p>{{ '%s is %d' | format('name',17) }}</p>
striptags:渲染之前把值中所有的HTML标签都删掉;
<p>{{ '<em>hello</em>' | striptags }}</p>
支持链式使用过滤器
<p>{{ “ hello world “ | trim | upper }}</p>
在模板目录index.html下更新如下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#支持链式操作#}
welcome to {{ ' neuedu '| trim | upper}}
</body>
</html>
Flask内置过滤器
Flask提供了一个内置过滤器”tojson”,它的作用是将变量输出为JSON字符串。这个在配合Javascript使用时非常有用
更新app.py文件 增加json数据
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/index')
def index():
data = '''
{
"name": "Python书籍",
"origin_price": 66,
"pub_date": "2018-4-14 17:00:00",
"store": ["京东", "淘宝"],
"author": ["张三", "李四", "Jhone"],
"is_valid": true,
"is_sale": false,
"meta": {
"isbn": "abc-123",
"pages": 300
},
"desc": null
}
'''
return render_template("index.html", data=data)
if __name__ == '__main__':
app.run()
更新index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#支持链式操作#}
welcome to {{ ' neuedu '| trim | upper}}
<script>
var data = {{ data | tojson |safe }}
console.log(data)
</script>
</body>
</html>
打开浏览器控制台