flask 学习笔记
环境
ubuntu17.10
python3.6
flask1.0.2
flask简介
Flask
是一个基于Python
开发并且依赖jinja2
模板和Werkzeug WSGI
服务的一个微型框架,对于Werkzeug
本质是Socket
服务端,其用于接收http请求并对请求进行预处理,然后触发Flask
框架,开发人员基于Flask
框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板
来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。
安装
python3环境下:
pip3 install flask
- 想要安装最新版本可以去
github
上下载 - 建议在python虚拟环境
virtalenv
中安装
最简单的应用
#!/usr/bin/env python3
# -*-coding:utf-8-*-
# power by jedi
from flask import Flask #导入Flask
app = Flask(__name__)#创建一个Flask实例
#路由
@app.route("/index")
def index():
return "Hello world"
if __name__ == "__main__":
app.run(debug=True)#使其可以运行在本地服务器
直接在终端运行
python3 hello.py
运行结果
* Serving Flask app "flask_hello_world" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 240-449-204
访问http://127.0.0.1:5000/index
即可出现第一个界面
访问之后控制台(终端)出现当前访问的状态
127.0.0.1 - - [05/Sep/2018 23:08:46] "GET /index HTTP/1.1" 200 -
运行结果
- debug=True
代表调试模式,不可用于正常的生产环境
入门
实例化Flask可选的参数
(self, import_name, static_path=None, static_url_path=None,
static_folder='static', template_folder='templates',
instance_path=None, instance_relative_config=False,
root_path=None)
参数解释:
1. template_folder
:模板所在的文件夹的名称
2. static_folder
:静态文件(css,js等)所在的目录
3. import_name
:应用包的名字
4. static_path
5. static_url_path
:静态文件地址的前缀,若不为空,访问静态文件时,就需要在前面加上
app = Flask(__name__,template_folder='templates',static_url_path='/test')
在根目录下创建目录,templates和static,则return render_template时,可以找到里面的模板页面;如在static文件夹里存放logo.png,在引用该图片时,静态文件地址为:/test/logo.png.
6. instance_path
和instance_relative_config
:这两个一般配合使用,
instance_ralative_config
的值为True
时,from_pyfile
会从instance_path
指定的地址下查找文件
instance_path
:指定from_pyfile查询文件的路径,不设置时,默认寻找和app.run()的执行文件同级目录下的instance文件夹;如果配置了instance_path(注意需要是绝对路径),就会从指定的地址下里面的文件
7. root_path
:当前执行文件所在目录
路由 app.route()
上面的第一个hello-world代码中的使用装饰器为路由配置
@app.route("/test")
def index():
pass
添加路由的本质:将url和视图函数封装成一个Rule对象,添加到Flask的url_map字段中
查看所有的路由
>>> app.url_map
Map([<Rule '/' (HEAD, GET, OPTIONS) -> index>,
<Rule '/static/<filename>' (HEAD, GET, OPTIONS) -> static>])
带参数路由 app.route()
#!/usr/bin/env python3
# -*-coding:utf-8-*-
# power by jedi
from flask import Flask
app = Flask(__name__)
@app.route("/user/<name>")
def name_info(name):
return "hello %s" % name
if __name__ == '__main__':
app.run(debug=True)
访问http://127.0.0.1:5000/user/jedi
界面输出
hello jedi
其中的可变参数可限制类型
@app.route(‘/user/’) #常用的 不加参数的时候默认是字符串形式的
@app.route(‘/post/’) #常用的 #指定int,说明是整型的
@app.route(‘/post/’)
@app.route(‘/post/’)
@app.route(‘/login’, methods=[‘GET’, ‘POST’])
return 的值
在函数(可以访问的,带路由的)中可以return
的有:
1. 字符串
: 如:
python
@app.route("/user/<name>")
def name_info(name):
return "hello %s" % name
2. render_template
,使用模板
3. make_response
,response
4. redirect()
请求的上下文 – request
获取get请求的参数实例
#!/usr/bin/env python3
# -*-coding:utf-8-*-
# power by jedi
from flask import Flask, request
app = Flask(__name__)
@app.route("/request_test")
def req_test():
val = ""
for key, value in request.args.items():
val += "%s = %s <br>" % (key, value)
return val
if __name__ == "__main__":
app.run(debug=True)
访问http://127.0.0.1:5000/request_test?name=jedi&age=22
界面输出:
name = jedi
age = 22
获取POST请求的参数实例,必须在app.route()中传入methods
参数的值包含有POST
#!/usr/bin/env python3
# -*-coding:utf-8-*-
# power by jedi
from flask import Flask, request
app = Flask(__name__)
@app.route("/request_test",methods=["GET","POST"])
def req_test():
val = ""
# for key, value in request.args.items():
for key, value in request.form.items():
val += "%s = %s <br>" % (key, value)
return val
if __name__ == "__main__":
app.run(debug=True)
获取http请求头的所有信息:
#!/usr/bin/env python3
# -*-coding:utf-8-*-
# power by jedi
from flask import Flask, request
app = Flask(__name__)
@app.route("/request_test", methods=["GET", "POST"])
def req_test():
val = ""
# for key, value in request.args.items():
# for key, value in request.form.items():
for key, value in request.headers.items():
val += "%s = %s <br>" % (key, value)
return val
if __name__ == "__main__":
app.run(debug=True)
界面结果
Host = 127.0.0.1:5000
Connection = keep-alive
Cache-Control = max-age=0
Upgrade-Insecure-Requests = 1
User-Agent = Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/67.0.3396.99 Chrome/67.0.3396.99 Safari/537.36
Accept = text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8
Accept-Encoding = gzip, deflate, br
Accept-Language = zh-CN,zh;q=0.9
Cookie = session=eyJ1c2VyX2luZm8iOiJqZWRpIn0.DnELUA.L5v8VhHKgGJd5wVOwblcqlqNCME
获取某一项的值:
value = request.headers.get("Host")
return value
另一种常见的还有request.querystring
# GET请求,bytes形式
flask 自带的系统上下文一共有四个:
current_app 约等于application
g 一个用于临时存储的对象 约等于viewbag
request 与servlet或asp.net中含义大体相同
session 与servlet或asp.net中含义大体相同
响应 – make_response
flask 中使用make_response
对象作为响应,用法和java sevlet类似
响应实例
#!/usr/bin/env python3
# -*-coding:utf-8-*-
# power by jedi
from flask import make_response, Flask
app = Flask(__name__)
@app.route("/response_test")
def index():
response = make_response("<h3>This is response content</h3>")
response.set_cookie("name", "jedi") # set cookie
return response
if __name__ == "__main__":
app.run(debug=True)
运行结果在浏览器中打印出内容,并且成功设置一个cookie
设置HTTP头
response.headers['xxx'] = '123123'
return response
转跳 – redirect
from flask import redirect # 页头,导入redirect对象
@app.route("/")
def index():
return redirect("www.baidu.com/")
获取URL参数 – urlencode,quote,unquote
访问 URL:http://127.0.0.1:5000/?username=%E6%B1%A4%E5%A7%86&uid=1
from flask import Flask, request
from urllib.parse import urlencode, quote, unquote
app = Flask(__name__)
@app.route("/")
def index():
if request.method == "GET":
s1 = request.args
s2 = request.args.to_dict()
s3 = urlencode(s2)
s4 = unquote(s3)
s5 = quote(s3)
print("s1:", s1)
print("s2:", s2)
print("s3:", s3)
print("s4:", s4)
print("s5:", s5)
return "test page"
if __name__ == '__main__':
app.run(debug=True)
s1: ImmutableMultiDict([(‘username’, ‘汤姆’), (‘uid’, ‘1’)])
s2: {‘username’: ‘汤姆’, ‘uid’: ‘1’}
s3: username=%E6%B1%A4%E5%A7%86&uid=1
s4: username=汤姆&uid=1
s5: username%3D%25E6%25B1%25A4%25E5%25A7%2586%26uid%3D1
反向生成url – url_for
@app.route()
的参数endpoint("name")
的作用是设置别名,用来反向生成URL。
实例:
from flask import Flask, url_for
app = Flask(__name__)
@app.route("/", endpoint="name")
def index():
v = url_for("name")
print(v)
return "Index"
@app.route("/index/<int:nid>", endpoint="name1")
def index1(nid):
v = url_for("name1", nid=nid)
print(v)
return "Index2"
if __name__ == '__main__':
app.run(debug=True)
分别访问两个链接终端打印的结果:
/
127.0.0.1 - - [06/Sep/2018 18:01:36] "GET /" 200 -
/index/222
127.0.0.1 - - [06/Sep/2018 18:01:54] "GET /index/222 HTTP/1.1" 200 -
自定义响应码
一般的响应码可以直接在return的返回字符串使用
实例:
#!/usr/bin/env python3
# -*-coding:utf-8-*-
# power by jedi
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "Test Text", 600
if __name__ == "__main__":
app.run(debug=True)
```
访问返回的HTTP状态变成自定义的`600`
```
127.0.0.1 - - [06/Sep/2018 14:00:44] "GET / HTTP/1.1" 600 -
此外flask中还提供一个错误码专用的函数 abort(code)
#!/usr/bin/env python3
# -*-coding:utf-8-*-
# power by jedi
from flask import Flask, abort
app = Flask(__name__)
@app.route("/")
def index():
# return "Test Text", 600
abort(500)
return "test"
if __name__ == "__main__":
app.run(debug=True)
此时浏览会报
内部服务器错误
服务器遇到内部错误,无法完成您的请求。服务器过载或应用程序中存在错误。
- tip:使用abort()函数时,返回的错误码必须在官方的错误码范围之内
后言
留空,共勉