【Python】【Flask】
生活随笔
收集整理的這篇文章主要介紹了
【Python】【Flask】
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
【快速開(kāi)始】
from flask import Flask, url_for, render_template, redirectapp = Flask(__name__)
"""
# kaishi
@app.route('/')
def index():
return 'Index Page'
@app.route('/hello')
def hello():
return 'Hello Flask World!!'
# param
@app.route('/user/<username>')
def show_user_profile(username):
return 'User %s' % (username)
@app.route('/post/<int:post_id>')
def show_post(post_id):
return 'Post %d' % (post_id)
# 重定向
@app.route('/projects/')
def projects():
return 'The projects page'
@app.route('/about')
def about():
return 'The about page'
# eg.. url_for 1
@app.route('/')
def index():
return 'hello'
@app.route('/login')
def login():
return 'login'
@app.route('/user/<username>')
def profile(username):
return 'profile %s' % username
with app.test_request_context():
print (url_for('index'))
print (url_for('login'))
print (url_for('login', ui='/'))
print (url_for('profile', username='Jone'))
'''
/
/login
/login?ui=%2F
/user/Jone
'''
# eg.. url_for 2
@app.route('/')
def index():
return 'hello'
@app.route('/login')
def Login():
return 'login'
@app.route('/user/<username>')
def profile(username):
return 'profile %s' % username
with app.test_request_context():
print (url_for('index'))
print (url_for('login'))
print (url_for('login', ui='/'))
print (url_for('profile', username='Jone'))
'''
werkzeug.routing.BuildError: Could not build url for endpoint 'login'. Did you mean 'Login' instead?
'''
#eg..
@app.route('/user/<username>/<userid>')
def user_index(username, userid):
return render_template('index.html', username=username)
@app.route('/')
def index():
return redirect(url_for('user_index', username='default', userid=99))
'''
網(wǎng)站輸入http://localhost:5000/
自動(dòng)指向http://localhost:5000/user/default/99
網(wǎng)頁(yè)內(nèi)容是test_one.html內(nèi)容
<index.html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
LOGIN IN!!
</body>
</html>
【注意】模版的位置放在templates文件夾下,一般是html文件
'''
@app.route('/')
def index():
list1 = list(range(10))
my_list = [{'id': 1, 'value': '我愛(ài)工作'},
{'id': 2, 'value': '工作使人快樂(lè)'},
{'id': 3, 'value': '沉迷于工作無(wú)法自拔'},
{'id': 4, 'value': '日漸消瘦'},
{'id': 5, 'value': '以夢(mèng)為馬,越騎越瘦'}]
return render_template(
#渲染模版語(yǔ)言
'index.html',
title = 'hello flask world',
list2 = list1,
my_list = my_list
)
#step1 定義過(guò)濾器
def do_listreverse(li):
temp_li = list(li)
temp_li.reverse()
return temp_li
#step2 添加自定義過(guò)濾器
app.add_template_filter(do_listreverse, 'listreverse')
'''
網(wǎng)站輸入http://localhost:5000/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{title|reverse|upper}}</h1>
<br>
{{list2 | listreverse}}
<br>
<ul>
{% for item in my_list %}
<li>{{item.id}}---{{item.value}}</li>
{% endfor %}
</ul>
{% for item in my_list %}
{% if loop.index==1 %}
<li style="">{{loop.index}}--{{item.get('value')}}</li>
{% elif loop.index==2 %}
<li style="">{{loop.index}}--{{item.value}}</li>
{% elif loop.index==3 %}
<li style="">{{item.id}}--{{item.value}}</li>
{% else %}
<li style="">{{item.id}}--{{item.value}}</li>
{% endif %}
{% endfor %}
</body>
</html>
【備注】
常見(jiàn)內(nèi)建過(guò)濾器
字符串操作
safe:禁用轉(zhuǎn)義
<p>{{ '<em>hello</em>' | safe }}</p>
capitalize:把變量值的首字母轉(zhuǎn)成大寫(xiě),其余字母轉(zhuǎn)小寫(xiě)
<p>{{ 'hello' | capitalize }}</p>
lower:把值轉(zhuǎn)成小寫(xiě)
<p>{{ 'HELLO' | lower }}</p>
upper:把值轉(zhuǎn)成大寫(xiě)
<p>{{ 'hello' | upper }}</p>
title:把值中的每個(gè)單詞的首字母都轉(zhuǎn)成大寫(xiě)
<p>{{ 'hello' | title }}</p>
reverse:字符串反轉(zhuǎn)
<p>{{ 'olleh' | reverse }}</p>
format:格式化輸出
<p>{{ '%s is %d' | format('name',17) }}</p>
striptags:渲染之前把值中所有的HTML標(biāo)簽都刪掉
<p>{{ '<em>hello</em>' | striptags }}</p>
truncate: 字符串截?cái)?br />
<p>{{ 'hello every one' | truncate(9)}}</p>
列表操作
first:取第一個(gè)元素
<p>{{ [1,2,3,4,5,6] | first }}</p>
last:取最后一個(gè)元素
<p>{{ [1,2,3,4,5,6] | last }}</p>
length:獲取列表長(zhǎng)度
<p>{{ [1,2,3,4,5,6] | length }}</p>
sum:列表求和
<p>{{ [1,2,3,4,5,6] | sum }}</p>
sort:列表排序
<p>{{ [6,2,3,1,5,4] | sort }}</p>
語(yǔ)句塊操作
{% filter upper %}
#一大堆文字#
{% endfilter %}
'''
# egg.. 靜態(tài)文件
@app.route('/')
def template1():
democss = url_for('static', filename='css/demo.css')
print (democss)
return render_template('index.html', democss=democss)
'''
【/templates/index.html】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--
這是第一種方式
<link href="/static/css/demo.css" rel="stylesheet" type="text/css"/>
這是第二種方式
-->
<link href="{{democss}}" rel="stylesheet" type="text/css"/>
</head>
<body>
<h1>Hello Flask World!!</h1>
</body>
</html>
【/static/css/demo.css】
body{
color:red;
}
【執(zhí)行】
瀏覽器訪(fǎng)問(wèn)http://localhost:5000
'''
# egg.. GET POST request
from flask import Flask,request
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def home():
return '<h1>Home</h1>'
@app.route('/signin', methods=['GET'])
def signin_form():
return '''
<form action="/signin" method="post">
<p><input name="username"></p>
<p><input name="password" type="password"></p>
<p><button type="submit">Sign in</button></p>
</form>
'''
@app.route('/signin', methods=['POST'])
def signin():
#需要從request對(duì)象讀取表單內(nèi)容
if request.form['username']=='admin' and request.form['password']=='password':
return '<h3>Hello , admin!!</h3>'
return '<h3>Bad username or password .</h3>'
'''
wang xue, [14.05.19 11:44]
運(yùn)行python app.py,Flask自帶的Server在端口5000上監(jiān)聽(tīng):
$ python app.py
* Running on http://127.0.0.1:5000/
打開(kāi)瀏覽器,輸入首頁(yè)地址http://localhost:5000/:
首頁(yè)顯示正確!
再在瀏覽器地址欄輸入http://localhost:5000/signin,會(huì)顯示登錄表單:
輸入預(yù)設(shè)的用戶(hù)名admin和口令password,登錄成功:
輸入其他錯(cuò)誤的用戶(hù)名和口令,登錄失敗:
'''
# egg.. 廖雪峰模版的例子
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def home():
return render_template('home.html')
@app.route('/signin', methods=['GET'])
def signin_form():
return render_template('form.html')
@app.route('/signin', methods=['POST'])
def signin():
username = request.form['username']
password = request.form['password']
if username=='admin' and password=='password':
return render_template('signin-ok.html', username=username)
return render_template('form.html', message='Bad username or password', username=username)
'''
【/templates/home.html】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<h1 style="font-style: italic">Home</h1>
</body>
</html>
【/templates/form.html】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Please Sign In</title>
</head>
<body>
{% if message %}
<p style="color:red">{{ message }}</p>
{% endif %}
<form action="/signin" method="post">
<legend>Please sign in:</legend>
<p><input name="username" placeholder="Username" value="{{ username }}"></p>
<p><input name="password" placeholder="Password" type="password"></p>
<p><button type="submit">Sign In</button></p>
</form>
</body>
</html>
【/templates/sign-ok.html】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome, {{ username }}</title>
</head>
<body>
<p>Welcome, {{ username }}</p>
</body>
</html>
'''
# egg .. 上下文
'''
https://www.cnblogs.com/Erick-L/p/6991079.html
Flask Markup 上下文,request
在模板渲染中,使用Markup轉(zhuǎn)換變量中的特殊字符
from flask import Markup
Markup函數(shù)對(duì)字符串進(jìn)行轉(zhuǎn)移處理再傳遞給render_template()函數(shù)
在瀏覽器中顯示標(biāo)簽代碼
路由地址的反響生成
通過(guò)函數(shù)名獲得與其綁定的Url地址
需要使用url_for函數(shù)進(jìn)行反向解析
with app.text_request_context()
print(url_for('f_root')) # 輸出:/
app.text_request_context()方法告訴解釋器為在其作用域中的代碼模擬一個(gè)HTTP請(qǐng)求上下文,使其好像被一個(gè)HTTP請(qǐng)求所調(diào)用
使用Context上下文
他是服務(wù)器端獲得應(yīng)用及請(qǐng)求相關(guān)信息的對(duì)象
1、會(huì)話(huà)上下文
會(huì)話(huà)(session)是一種客戶(hù)端與服務(wù)器端保持狀態(tài)的解決方案,會(huì)話(huà)上下文是用來(lái)實(shí)現(xiàn)這種解決方案的存儲(chǔ)結(jié)構(gòu)
復(fù)制代碼
from flask import Flask,session
from datetime import datetime
app = Flask(__name__)
app.secret_key = 'SET_ME_BEFORE_USE_SESSION'
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/write_session')
def wirteSession():
session['key_time']=datetime.now().strftime('%Y-%m-%d %H:%M:%S')# 將當(dāng)前時(shí)間保存在Session中
return session['key_time'] # 返回當(dāng)前時(shí)間
@app.route('/read_session')
def readSession():
return session.get('key_time')# 獲取上次調(diào)用wirteSession時(shí)寫(xiě)入的時(shí)間并返回
復(fù)制代碼
除了正常的數(shù)據(jù)保存和讀取,flask.session對(duì)象還維護(hù)自身的狀態(tài),通過(guò)
new 判斷本次請(qǐng)求的Session是否時(shí)新建的
modified 判斷本次請(qǐng)求中是否修改過(guò)Session鍵值
@app.route('/write_session')
def wirteSession():
session['key_time']=time.time() # 將當(dāng)前時(shí)間保存在Session中
return session.modified # 因?yàn)橹斑M(jìn)行了Session設(shè)置,所以判斷本次請(qǐng)求是否被修改過(guò)(modified)返回TRUE
應(yīng)用全局對(duì)象
復(fù)制代碼
from flask import Flask,g
class MYDB():
def __init__(self):
print('一個(gè)數(shù)據(jù)庫(kù)鏈接已經(jīng)建立')
def close(self):
print('數(shù)據(jù)庫(kù)已經(jīng)關(guān)閉')
def connect_to_database():
return MYDB()
def get_db():
db = getattr(g,'_database',None)
if db is None:
db = connect_to_database()
g._database = db # 存入Flask.g對(duì)象中
return db
@app.teardown_request # 在請(qǐng)求結(jié)束時(shí)自動(dòng)被Flask框架調(diào)用
def teardown_db(response):
db = getattr(g,'_database',None)# 從Flask.g對(duì)象中獲取對(duì)象,檢查是否有鏈接數(shù)據(jù)庫(kù)對(duì)象,如果有則關(guān)閉
if db is not None:
db.close()
復(fù)制代碼
可以在請(qǐng)求處理函數(shù)的任何地方調(diào)用get_db()
復(fù)制代碼
class MYDB():
def __init__(self):
print('一個(gè)數(shù)據(jù)庫(kù)鏈接已經(jīng)建立')
def close(self):
print('數(shù)據(jù)庫(kù)已經(jīng)關(guān)閉')
def connect_to_database():
return MYDB()
def get_db():
db = getattr(g,'_database',None)
if db is None:
db = connect_to_database()
g._database = db # 存入Flask.g對(duì)象中
return db
@app.teardown_request
def teardown_db(response):
db = getattr(g,'_database',None)# 從Flask.g對(duì)象中獲取對(duì)象
if db is not None:
db.close()
def login():
db=get_db() # 第一次調(diào)用getdb 創(chuàng)建數(shù)據(jù)庫(kù)鏈接
session['has_login']=True
# 使用db檢查數(shù)據(jù)庫(kù)中的用戶(hù)名和密碼
def view_list():
if 'has_login' not in session:
login()
db = get_db() # 第二次調(diào)用get_db()# 直接復(fù)用之前建立的鏈接
# 使用db 從數(shù)據(jù)庫(kù)查詢(xún)數(shù)據(jù),返回teardown_db()將會(huì)被自動(dòng)調(diào)用
復(fù)制代碼
請(qǐng)求上下文生命周期
復(fù)制代碼
from flask import Flask, g, request
app = Flask(__name__)
@app.before_request
def before_request():
print 'before request started'
print request.url
@app.before_request
def before_request2():
print 'before request started 2'
print request.url
g.name="SampleApp"
@app.after_request
def after_request(response):
print 'after request finished'
print request.url
response.headers['key'] = 'value'
return response
@app.teardown_request
def teardown_request(exception):
print 'teardown request'
print request.url
@app.route('/')
def index():
return 'Hello, %s!' % g.name
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
復(fù)制代碼
訪(fǎng)問(wèn)”http://localhost:5000/”后,會(huì)在控制臺(tái)輸出:
復(fù)制代碼
before request started
http://localhost:5000/
before request started 2
http://localhost:5000/
after request finished
http://localhost:5000/
teardown request
http://localhost:5000/
復(fù)制代碼
request對(duì)象只有在請(qǐng)求上下文的生命周期內(nèi)才可以訪(fǎng)問(wèn)。離開(kāi)了請(qǐng)求的生命周期,其上下文環(huán)境也就不存在了,自然也無(wú)法獲取request對(duì)象。而上面介紹的幾個(gè)由上下文裝飾器修飾的Hook函數(shù),會(huì)掛載在請(qǐng)求生命周期內(nèi)的不同階段,所以其內(nèi)部可以訪(fǎng)問(wèn)request對(duì)象。
構(gòu)建請(qǐng)求上下文環(huán)境
我們使用Flask的內(nèi)部方法”request_context()”來(lái)構(gòu)建一個(gè)客戶(hù)端請(qǐng)求上下文。
復(fù)制代碼
from werkzeug.test import EnvironBuilder
ctx = app.request_context(EnvironBuilder('/','http://localhost/').get_environ())
ctx.push()
try:
print request.url
finally:
ctx.pop()
復(fù)制代碼
“request_context()”會(huì)創(chuàng)建一個(gè)請(qǐng)求上下文”RequestContext”類(lèi)型的對(duì)象,其需接收”werkzeug”中的”environ”對(duì)象為參數(shù)。”werkzeug”是Flask所依賴(lài)的WSGI函數(shù)庫(kù)
我們可以在客戶(hù)端的請(qǐng)求之外訪(fǎng)問(wèn)request對(duì)象,其實(shí)此時(shí)的request對(duì)象即是剛創(chuàng)建的請(qǐng)求上下文中的一個(gè)屬性”request == ctx.request”。啟動(dòng)Flask時(shí),控制臺(tái)仍然可以打印出訪(fǎng)問(wèn)地址”http://localhost/”。上面的代碼可以用with語(yǔ)句來(lái)簡(jiǎn)化:
from werkzeug.test import EnvironBuilder
with app.request_context(EnvironBuilder('/','http://localhost/').get_environ()):
print request.url
請(qǐng)求上下文的實(shí)現(xiàn)方式
對(duì)于Flask Web應(yīng)用來(lái)說(shuō),每個(gè)請(qǐng)求就是一個(gè)獨(dú)立的線(xiàn)程。請(qǐng)求之間的信息要完全隔離,避免沖突,這就需要使用本地線(xiàn)程環(huán)境(ThreadLocal),
”ctx.push()”方法,會(huì)將當(dāng)前請(qǐng)求上下文,壓入”flask._request_ctx_stack”的棧中,同時(shí)這個(gè)”_request_ctx_stack”棧是個(gè)ThreadLocal對(duì)象,也就是”flask._request_ctx_stack”看似全局對(duì)象,其實(shí)每個(gè)線(xiàn)程的都不一樣。請(qǐng)求上下文壓入棧后,再次訪(fǎng)問(wèn)其都會(huì)從這個(gè)棧的頂端通過(guò)”_request_ctx_stack.top”來(lái)獲取,所以取到的永遠(yuǎn)是只屬于本線(xiàn)程中的對(duì)象,這樣不同請(qǐng)求之間的上下文就做到了完全隔離。請(qǐng)求結(jié)束后,線(xiàn)程退出,ThreadLocal線(xiàn)程本地變量也隨即銷(xiāo)毀,”ctx.pop()”用來(lái)將請(qǐng)求上下文從棧里彈出,避免內(nèi)存無(wú)法回收。
——————————————————————————————————————————————————————————————————————
主要是在服務(wù)端獲得從客戶(hù)端提交的數(shù)據(jù),包括url參數(shù),表單數(shù)據(jù),cookies等
復(fù)制代碼
from flask import Flask,request,url_for,redirect
app = Flask(__name__)
@app.route('/redirect_url')
def redirect_url():
next = request.args.get('next') or url_for('index')
return redirect(next)
@app.route('/echo_url')
def echo_url():
return request.base_url
復(fù)制代碼
自定義上下文變量和函數(shù)
自定義變量
from flask import current_app
@app.context_processor
def appinfo():
return dict(appname=current_app.name)
函數(shù)返回的是一個(gè)字典,里面有一個(gè)屬性”appname”,值為當(dāng)前應(yīng)用的名稱(chēng)。我們?cè)?jīng)介紹過(guò),這里的”current_app”對(duì)象是一個(gè)定義在應(yīng)用上下文中的代理。函數(shù)用”@app.context_processor”裝飾器修飾,它是一個(gè)上下文處理器,它的作用是在模板被渲染前運(yùn)行其所修飾的函數(shù),并將函數(shù)返回的字典導(dǎo)入到模板上下文環(huán)境中,與模板上下文合并。然后,在模板中”appname”成為了可訪(fǎng)問(wèn)的上下文對(duì)象。我們可以在模板中將其輸出:
<p>Current App is: {{ appname }}</p>
自定義函數(shù)
同理我們可以自定義上下文函數(shù),只需將上例中返回字典的屬性指向一個(gè)函數(shù)即可,下面我們就來(lái)定義一個(gè)上下文函數(shù)來(lái)獲取系統(tǒng)當(dāng)前時(shí)間:
復(fù)制代碼
import time
@app.context_processor
def get_current_time():
def get_time(timeFormat="%b %d, %Y - %H:%M:%S"):
return time.strftime(timeFormat)
return dict(current_time=get_time)
復(fù)制代碼
<p>Current Time is: {{ current_time() }}</p>
<p>Current Day is: {{ current_time("%Y-%m-%d") }}</p>
應(yīng)用上下文環(huán)境
current_app代理
復(fù)制代碼
from flask import Flask, current_app
app = Flask('SampleApp')
@app.route('/')
def index():
return 'Hello, %s!' % current_app.name
復(fù)制代碼
我們可以通過(guò)”current_app.name”來(lái)獲取當(dāng)前應(yīng)用的名稱(chēng),也就是”SampleApp”。”current_app”是一個(gè)本地代理,它的類(lèi)型是”werkzeug.local. LocalProxy”,它所代理的即是我們的app對(duì)象,也就是說(shuō)”current_app == LocalProxy(app)”。使用”current_app”是因?yàn)樗彩且粋€(gè)ThreadLocal變量,對(duì)它的改動(dòng)不會(huì)影響到其他線(xiàn)程。你可以通過(guò)”current_app._get_current_object()”方法來(lái)獲取app對(duì)象。
既然是ThreadLocal對(duì)象,那它就只在請(qǐng)求線(xiàn)程內(nèi)存在,它的生命周期就是在應(yīng)用上下文里。離開(kāi)了應(yīng)用上下文,”current_app”一樣無(wú)法使用
構(gòu)建應(yīng)用上下文環(huán)境
同請(qǐng)求上下文一樣,我們也可以手動(dòng)構(gòu)建應(yīng)用上下文環(huán)境:
with app.app_context():
print current_app.name
“app_context()”方法會(huì)創(chuàng)建一個(gè)”AppContext”類(lèi)型對(duì)象,即應(yīng)用上下文對(duì)象,此后我們就可以在應(yīng)用上下文中,訪(fǎng)問(wèn)”current_app”對(duì)象了。
應(yīng)用上下文Hook函數(shù)
應(yīng)用上下文也提供了裝飾器來(lái)修飾Hook函數(shù),不過(guò)只有一個(gè)”@app.teardown_appcontext”。它會(huì)在應(yīng)用上下文生命周期結(jié)束前,也就是從”_app_ctx_stack”出棧時(shí)被調(diào)用。我們可以加入下面的代碼,順便也驗(yàn)證下,是否應(yīng)用上下文在每個(gè)請(qǐng)求結(jié)束時(shí)會(huì)被銷(xiāo)毀。
@app.teardown_appcontext
def teardown_db(exception):
print 'teardown application'
request的屬性
下面是request可使用的屬性,其中黑體是比較常用的。
form
一個(gè)從POST和PUT請(qǐng)求解析的 MultiDict(一鍵多值字典)。
args
MultiDict,要操作 URL (如 ?key=value )中提交的參數(shù)可以使用 args 屬性:
searchword = request.args.get('key', '')
values
CombinedMultiDict,內(nèi)容是form和args。
可以使用values替代form和args。
cookies
顧名思義,請(qǐng)求的cookies,類(lèi)型是dict。
stream
在可知的mimetype下,如果進(jìn)來(lái)的表單數(shù)據(jù)無(wú)法解碼,會(huì)沒(méi)有任何改動(dòng)的保存到這個(gè)·stream·以供使用。很多時(shí)候,當(dāng)請(qǐng)求的數(shù)據(jù)轉(zhuǎn)換為string時(shí),使用data是最好的方式。這個(gè)stream只返回?cái)?shù)據(jù)一次。
headers
請(qǐng)求頭,字典類(lèi)型。
data
包含了請(qǐng)求的數(shù)據(jù),并轉(zhuǎn)換為字符串,除非是一個(gè)Flask無(wú)法處理的mimetype。
files
MultiDict,帶有通過(guò)POST或PUT請(qǐng)求上傳的文件。
environ
WSGI隱含的環(huán)境配置。
method
請(qǐng)求方法,比如POST、GET。
path
script_root
url
base_url
url_root
如果用戶(hù)請(qǐng)求如下URL:
http://www.example.com/myapplication/page.html?x=y
以上的參數(shù)內(nèi)容如下:
名稱(chēng) 內(nèi)容
path /page.html
script_root /myapplication
base_url http://www.example.com/myapplication/page.html
url http://www.example.com/myapplication/page.html?x=y
url_root http://www.example.com/myapplication/
is_xhr
如果請(qǐng)求是一個(gè)來(lái)自JavaScript XMLHttpRequest的觸發(fā),則返回True,這個(gè)只工作在支持X-Requested-With頭的庫(kù)并且設(shè)置了XMLHttpRequest。
blurprint
藍(lán)本名字。
endpoint
endpoint匹配請(qǐng)求,這個(gè)與view_args相結(jié)合,可是用于重構(gòu)相同或修改URL。當(dāng)匹配的時(shí)候發(fā)生異常,會(huì)返回None。
get_json(force=False, silent=False, cache=True)
json
如果mimetype是application/json,這個(gè)參數(shù)將會(huì)解析JSON數(shù)據(jù),如果不是則返回None。
可以使用這個(gè)替代get_json()方法。
max_content_length
只讀,返回MAX_CONTENT_LENGTH的配置鍵。
module
如果請(qǐng)求是發(fā)送到一個(gè)實(shí)際的模塊,則該參數(shù)返回當(dāng)前模塊的名稱(chēng)。這是棄用的功能,使用blueprints替代。
on_json_loading_failed(e)
routing_exception = None
如果匹配URL失敗,這個(gè)異常將會(huì)/已經(jīng)拋出作為請(qǐng)求處理的一部分。這通常用于NotFound異常或類(lèi)似的情況。
url_rule = None
內(nèi)部規(guī)則匹配請(qǐng)求的URL。這可用于在URL之前/之后檢查方法是否允許(request.url_rule.methods) 等等。
默認(rèn)情況下,在處理請(qǐng)求函數(shù)中寫(xiě)下
print('request.url_rule.methods', request.url_rule.methods)
會(huì)打印:
request.url_rule.methods {‘GET’, ‘OPTIONS’, ‘HEAD’}
view_args = None
一個(gè)匹配請(qǐng)求的view參數(shù)的字典,當(dāng)匹配的時(shí)候發(fā)生異常,會(huì)返回None。
'''
# egg. Cookies
from flask import request, make_response
app = Flask(__name__)
@app.route('/')
def index():
resp = make_response(render_template('index.html'))
resp.set_cookie('username', 'wangxue')
return resp
@app.route('/en')
def en():
username = request.cookies.get('username')
return username
'''
【index.html】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Hello Flask !!
</body>
</html>
首先訪(fǎng)問(wèn)localhost:5000 : 頁(yè)面顯示"Hello Flask"
再次訪(fǎng)問(wèn)localhost:5000/en: 頁(yè)面顯示"wangxue"
'''
# egg.. 重定向和錯(cuò)誤
from flask import Flask, abort, redirect, url_for, render_template
app = Flask(__name__)
@app.route('/')
def index():
return redirect(url_for('login'))
@app.route('/login')
def login():
abort(401)
this_is_never_executed()
def this_is_never_executed():
print ('*********************')
'''
訪(fǎng)問(wèn) localhost:5000
頁(yè)面顯示:
Unauthorized
The server could not verify that you are authorized to access the URL requested. You either supplied the wrong credentials (e.g. a bad password), or your browser doesn't understand how to supply the credentials required.
如果再加上下面代碼,則頁(yè)面顯示制定html內(nèi)容
@app.errorhandler(401)
def page_not_auth(error):
return render_template('page_not_auth.html'), 401
'''
# egg.. 響應(yīng)
一個(gè)視圖函數(shù)的返回值會(huì)被自動(dòng)轉(zhuǎn)換為一個(gè)響應(yīng)對(duì)象。如果返回值是一個(gè)字符串,它被轉(zhuǎn)換成一個(gè)響應(yīng)主體是該字符串,錯(cuò)誤代碼為 200 OK ,媒體類(lèi)型為 text/html 的響應(yīng)對(duì)象。 Flask 把返回值轉(zhuǎn)換成響應(yīng)對(duì)象的邏輯如下:
如果返回的是一個(gè)合法的響應(yīng)對(duì)象,它會(huì)被從視圖直接返回。
如果返回的是一個(gè)字符串,響應(yīng)對(duì)象會(huì)用字符串?dāng)?shù)據(jù)和默認(rèn)參數(shù)創(chuàng)建。
如果返回的是一個(gè)元組而且元組中元素能夠提供額外的信息。這樣的元組必須是 (response, status, headers) 形式且至少含有一個(gè)元素。 status 值將會(huì)覆蓋狀態(tài)代碼,headers 可以是一個(gè)列表或額外的消息頭值字典。
如果上述條件均不滿(mǎn)足,Flask 會(huì)假設(shè)返回值是一個(gè)合法的 WSGI 應(yīng)用程序,并轉(zhuǎn)換為一個(gè)請(qǐng)求對(duì)象。
如果你想要獲取在視圖中得到的響應(yīng)對(duì)象,你可以用函數(shù) make_response() 。
想象你有這樣一個(gè)視圖:
@app.errorhandler(404)
def not_found(error):
return render_template('error.html'), 404
你只需要用 make_response() 封裝返回表達(dá)式,獲取結(jié)果對(duì)象并修改,然后返回它:
@app.errorhandler(404)
def not_found(error):
resp = make_response(render_template('error.html'), 404)
resp.headers['X-Something'] = 'A value'
return resp
# egg... 會(huì)話(huà)
除了請(qǐng)求對(duì)象,還有第二個(gè)稱(chēng)為 session 對(duì)象允許你在不同請(qǐng)求間存儲(chǔ)特定用戶(hù)的信息。 這是在 cookies 的基礎(chǔ)上實(shí)現(xiàn)的,并且在 cookies 中使用加密的簽名。這意味著用戶(hù)可以查看 cookie 的內(nèi)容, 但是不能修改它,除非它知道簽名的密鑰。
要使用會(huì)話(huà),你需要設(shè)置一個(gè)密鑰。這里介紹會(huì)話(huà)如何工作:
from flask import Flask, session, redirect, url_for, escape, request
app = Flask(__name__)
@app.route('/')
def index():
if 'username' in session:
return 'Logged in as %s' % escape(session['username'])
return 'You are not logged in'
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
session['username'] = request.form['username']
return redirect(url_for('index'))
return '''
<form action="" method="post">
<p><input type=text name=username>
<p><input type=submit value=Login>
</form>
'''
@app.route('/logout')
def logout():
# remove the username from the session if it's there
session.pop('username', None)
return redirect(url_for('index'))
# set the secret key. keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
這里提到的 escape() 可以在你不使用模板引擎的時(shí)候做轉(zhuǎn)義(如同本例)。
怎樣產(chǎn)生一個(gè)好的密鑰
隨機(jī)的問(wèn)題在于很難判斷什么是真隨機(jī)。一個(gè)密鑰應(yīng)該足夠隨機(jī)。你的操作系統(tǒng)可以基于一個(gè)密碼隨機(jī)生成器來(lái)生成漂亮的隨機(jī)值,這個(gè)值可以用來(lái)做密鑰:
>>> import os
>>> os.urandom(24)
'\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\xa8'
把這個(gè)值復(fù)制粘貼到你的代碼,你就搞定了密鑰。
使用基于 cookie 的會(huì)話(huà)需注意: Flask 會(huì)將你放進(jìn)會(huì)話(huà)對(duì)象的值序列化到 cookie。如果你試圖尋找一個(gè)跨請(qǐng)求不能存留的值, cookies 確實(shí)是啟用的,并且你不會(huì)獲得明確的錯(cuò)誤信息,檢查你頁(yè)面請(qǐng)求中 cookie 的大小,并與 web 瀏覽器所支持的大小對(duì)比。
"""
if __name__ == '__main__':
app.debug = True
app.run(host='0.0.0.0')
轉(zhuǎn)載于:https://www.cnblogs.com/suren2017/p/10874592.html
總結(jié)
以上是生活随笔為你收集整理的【Python】【Flask】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 浅谈APP的分享功能,有时候社交裂变形式
- 下一篇: websocket python爬虫_p