python flask框架
hello world
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index(name):
return 'hello world!'
if __name__ == '__main__':
app.run()
保存为hello.py,这是flask框架制作的小应用,在命令行中运行python hello.py
,
访问 http://127.0.0.1:5000 就会看到hello world!
这里首先引入Flask类,实例化一个对象app,__name__
代表这个模块的名字。因为这个模块是直接被运行的,所以此时__name__
的值是__main__
。然后用route()这个修饰器定义了一个路由,告诉flask如何访问该函数。最后用run()函数使这个应用在服务器上运行起来。
路由
flask框架是通过route()装饰器将一个函数绑定到对应的url上。
例子:
from flask import Flask
app = Flask(__name__)
@app.route('/admin')
def admin():
return 'helllo admin!'
@app.route('/user')
def user():
return 'hello user!'
if __name__ == '__main__':
app.run()
按照上面的方法,运行脚本,访问http://127.0.0.1:5000/admin就会输出hello admin!。访问http://127.0.0.1:5000/user就会得到hello user!。
flask支持在路由上制定参数及参数类型,通过<variable_name>
(即:<变量名>)可以标记变量,这个部分将会作为命名参数传递到你的函数,也可以通过<converter:variable_name>
(即:<类型转换器:变量名>)指定一个可选的装饰器
实例:
from flask import Flask
app = Flask(__name__)
@app.route('/<name>')
def index(name):
return 'path %s'% name
if __name__ == '__main__':
app.run()
运行脚本后,我们访问http://127.0.0.1:5000/user,会看到 path user,当我们访问http://127.0.0.1:5000/user/时会报错,显示Not Found。
实例:
from flask import Flask
app = Flask(__name__)
@app.route('/<int:id>')
def id(id):
return 'path %d'% id
if __name__ == '__main__':
app.run()
运行脚本后,我们访问http://127.0.0.1:5000/user时会报错,显示Not Found。当我们访问http://127.0.0.1:5000/123时,会看到path 123,这里说名只能是int类型的即整型的才能访问的到。
类型转换器 | 作用 | 占位符标识 |
---|---|---|
缺省(即 :默认) | 字符型,不能出现斜线 | %s |
int | 整型 | %d |
float | 浮点型 | %f (默认小数点后六位) |
path | 字符型,可以有斜线 | %s |
HTTP方法
处理HTTP方法在Flask框架中是使用route装饰器的methods参数设置的。
from flask import request
from flask import Flask
app = Flask(__name__)
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return 'POST'
else:
return 'GET'
if __name__ == '__main__':
app.run()
当你请求地址http://localhost:5000/login,”GET”和”POST”请求会返回不同的内容,其他请求方法则会返回405错误。
唯一URL/重定向行为
Flask的URL规则是基于Werkzeug的路由模块。模块背后的思想是基于 Apache 以及更早的 HTTP 服务器主张的先例,保证优雅且唯一的 URL。
from flask import Flask
app = Flask(__name__)
@app.route('/admin/')
def projects():
return 'The admin page'
@app.route('/user')
def about():
return 'The user page'
if __name__ == '__main__':
app.run()
访问第一个路由不带/时,Flask会自动重定向到正确地址。
访问第二个路由时末尾带上/后Flask会直接报404 NOT FOUND错误。
构造url
Flask提供了url_for()
方法来快速获取和构造url,方法的第一个参数指向函数名(加过`@app.route`注解的函数),后续的参数对应于要构建的URL变量。
实例:
from flask import Flask,url_for
app = Flask(__name__)
@app.route('/log')
def login():
return url_for('login')
if __name__ == '__main__':
app.run()
访问http://localhost:5000/log得到`/log`。解释:返回的是路由地址,`url_for()`方法的第一个参数是路由里的函数名login。
url_for('login') # 返回/log
url_for('login', id='1') # 将id作为URL参数,返回/log?id=1
url_for('hello', name='man') # 适配hello函数的name参数,返回/hello/man
url_for('static', filename='style.css') # 静态文件地址,返回/static/style.css
Web程序中常常需要处理静态文件,在Flask中需要使用url_for
函数并指定static
端点名和文件名。在上面的例子中,实际的文件应放在static/
文件夹下。
实例:
from flask import Flask,url_for
app = Flask(__name__)
@app.route('/article/<id>/')
def article(id):
return 'article is detail'
@app.route('/')
def index():
return url_for("article",id='1')
if __name__ == '__main__':
app.run(host='10.10.166.142',port='9000',debug=True)
这时访问http://127.0.0.1:5000时返回/article/1/
request对象
from flask import Flask,request,render_template
app = Flask(__name__)
@app.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
if request.form['user'] == 'admin':
return 'Admin login successfully!'
else:
return 'No such user!'
title = request.args.get('title', 'Default')
return render_template('login.html', title=title)
if __name__ == '__main__':
app.run()
request.args.get()
方法则可以获取Get请求URL中的参数,该函数的第二个参数是默认值,当URL参数不存在时,则返回默认值。
templates目录下,添加layout.html
文件
<!doctype html>
<title>Hello Sample</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css') }}">
<div class="page">
{% block body %}
{% endblock %}
</div>
添加login.html
{% extends "layout.html" %}
{% block body %}
<form name="login" action="/login" method="post">
Hello {{ title }}, please login by:
<input type="text" name="user">
</form>
{% endblock %}
访问:http://127.0.0.1:5000/login 得到:Hello Default, please login by:输入框,我们get方式传参title=alex 得到:Hello alex, please login by:输入框,我们在输入框中输入admin,得到:Admin login successfully! 如果输入别的则得到No such user!
全局对象 g
flask.g
是Flask一个全局对象,g
的作用范围,就在一个请求(也就是一个线程)里,它不能在多个请求间共享。你可以在g
对象里保存任何你想保存的内容。
构建响应
from flask import Flask,request,session, make_response,render_template
app = Flask(__name__)
@app.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
pass
if 'user' in session:
pass
else:
title = request.args.get('title', 'Default')
response = make_response(render_template('login.html', title=title), 200)
response.headers['key'] = 'value'
return response
if __name__ == '__main__':
app.run()
make_response
方法就是用来构建response对象的,第二个参数代表响应状态码,缺省就是200。
会话对象session
会话可以用来保存当前请求的一些状态,以便于在请求之前共享信息。
登入
from flask import Flask,request,render_template,session
app=Flask(__name__)
@app.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'POST':
if request.form['user'] == 'admin':
session['user']=request.form['user']
return 'Admin login successfully!'
else:
return 'No such user!'
if 'user' in session:
return 'Hello %s!'%session['user']
else:
title = request.args.get('title', 'Default')
return render_template('login.html', title=title)
app.secret_key='123456'
if __name__=='__main__':
app.run()
使用session时一定要设置一个密钥app.secret_key
,密钥要尽量复杂,最好使用一个随机数。
登出
from flask import request, session, redirect, url_for
@app.route('/logout')
def logout():
session.pop('user', None)
return redirect(url_for('login'))
模板
模板生成
Flask默认使用Jinja2
作为模板,默认情况下,模板文件需要放在templates
文件夹下。
用 Jinja 模板,只需要使用render_template
函数并传入模板文件名和参数名即可。
from flask import render_template
@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
return render_template('hello.html', name=name)
hello()
函数并不是直接返回字符串,而是调用了render_template()
方法来渲染模板。方法的第一个参数hello.html
指向你想渲染的模板名称,第二个参数name
是你要传到模板去的变量,变量可以传多个。
hello.html代码:
<!Doctype html>
<title>Hello from Flask</title>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
变量或表达式由{{ }}修饰,而控制语句由{% %}修饰,其他的代码,就是我们常见的HTML。
模板标签
代码块需要包含在{% %}块中
{% extends 'layout.html' %}
{% block title %}主页{% endblock %}
{% block body %}
<div class="jumbotron">
<h1>主页</h1>
</div>
{% endblock %}