Flask從入門到入土(二)——請求响应與Flask扩展
————————————————————————————————————————————————————————————
一.程序和請求上下文
Flask從客戶端收到請求時,要讓視圖函數能訪問一些對象,這樣才能處理請求。請求對象就是一個很好的例子,它封裝了客戶端發送的Http請求。
要想讓視圖函數能夠訪問請求對象,一個顯而易見的方式是將其作爲參數傳入視圖函數,不過這會導致程序中的每個視圖函數都增加一個參數。除了訪問請求對象,如果視圖函數在處理請求時還要訪問其他對象,情況會變得糟糕。
爲了避免大量可有可無的參數,Flask使用了上下文臨時把某些對象變爲全局可訪問。有類上下文,就可以寫出下面的函數視圖。
from flask import Flask
from flask import request
app = Flask(__name__) @app.route('/')
def index():
user_agent = request.headers.get('User-Agent')
return '<h3>Your browser is %s</h3>' %user_agent if __name__=='__main__':
app.run()

在Flask中有兩種上下文:程序上下文和請求上下文。
程序上下文: current_app 當前激活程序的程序實例
g 處理請求時臨時用作臨時存儲對象。每次請求都會重置這個變量
請求上下文: request 請求對象,封裝了客戶端發出的HTTP請求中的內容
session 用戶會話,用與存儲請求之間需要“記住”的值的詞典
Flask在發送請求之前激活程序和請求上下文,請求處理完成後再將其刪除。
下面這個Python shell會話演示了程序上下文的使用方法:
>>>from hello import app
>>>from flask import current_app
>>> current_app.name
Traceback (most recent call last):
...
RuntimeError:working outside of application context
>>> app_ctx = app.app_context()
>>> app_ctx.push()
>>> current_app.name
'hello'
>>> app_ctx.pop()
在沒有激活程序上下文之前就調用current_app.name會導致錯誤,但推送完上下文之後就可以調用了。
注意:在程序實例中調用app.app_context()可獲得一個程序上下文。
————————————————————————————————————————————————————————————
二.請求調度
程序收到客戶端發來的請求時,要找到處理該請求的視圖函數。爲了完成這個任務,Flask會在程序的URL映射中查找請求的URL。URL映射是URL和視圖函數之間的對應關系。Flask使用app.route修飾器或者非修飾器形式的app.add_url_rule()生成映射。
URL映射中的HEAD,Options,GET是請求方法,由路由進行處理。Flask爲每一個URL都指定了請求方法,這樣不同的請求方法發送到相同的URL上時,會使用不同的視圖函數進行處理。HEAD和OPTIONS方法由Flask自動處理,其他都書GET方法。
三.請求鉤子
有時在處理請求之前或之後執行代碼會很有用。例如,在請求開始時,我們可能需要創建數據庫連接或者認證發起請求的用戶。爲了避免在每個視圖中都使用重復的代碼,Flask提供了注冊通用函數的功能,注冊函數可在請求被分發到視圖函數之前或之後調用。
請求鉤子使用修飾器實現,Flask支持以下4種鉤子。
*before_first_request : 注冊一個函數,在處理第一個請求之前運行。
*before_request : 注冊一個函數,在每次請求之前運行。
*after_request : 注冊一個函數,如果沒有處理異常的拋出,在每次請求之後運行。
*teardown_request : 注冊一個函數,即使有未處理的異常拋出,也在每次請求之後運行。
在請求鉤子函數和視圖函數之間共享數據一般使用上下文全局變量g。例如,before_request處理程序可以從數據庫中加載已登錄用戶,並將其保存到g.user中。隨後調用視圖函數時,視圖函數再使用g.user獲取用戶。
四.响应
Flask調用視圖函數後,會將其返回值作爲响应的內容。大多數情況下,响应就是一個簡單的字符串,作爲HTML頁面送回客戶端。
但HTTP協議需要的不僅是作爲請求响应的字符串。HTTP响应中一個很重要的部分是狀態碼,Flask默認設置是200,這個代碼表明請求已經被成功處理。
Flask還可以返回Response對象。make_response()函數可以接受1個,2個或3個參數。並返回一個Response對象。有時我們需要在視圖函數中進行這種轉換,然後在響應對象上調用各種方法,進一步設置響應。
from flask import Flask
from flask import make_response app = Flask(__name__) @app.route('/')
def index():
response = make_response('<h1>This is document</h1>')
response.set_cookie('answer','yooooooo~')
return response if __name__=='__main__':
app.run()


有一種名爲重定向的特殊响应類型。這種响应沒有頁面文檔,只告訴瀏覽器一個新地址用以加載新頁面。重定向經常在Web表單中使用。狀態碼一般是302,指向的地址由Location首部提供。重定向响应可以使用3個形式的返回值生成,也可以在Response對象中設定。不過,由於使用頻繁,Flask提供了redirect()輔助函數,用於生成這種響應:
from flask import Flask
from flask import redirect app = Flask(__name__) @app.route('/')
def index():
return redirect('http://www.baidu.com') if __name__=='__main__':
app.run()
重定向至http://www.baidu.com
還有一種特殊响应由abort函數生成,用於處理錯誤。如果URL中動態參數ID對應用戶不存在,就返回狀態碼404:
from flask import Flask
from flask import abort app = Flask(__name__) @app.route('/')
def index():
return 'hello' @app.route('/user/<id>')
def user(id):
user = load_user(id)
if not user:
abort(404)
return 'hello,%s' %user.name if __name__=='__main__':
app.run()
五.Flask扩展
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return '<h7>hello</h7>'
if __name__=='__main__':
app.run(host='192.168.1.8')
之後便可在統一網絡下使用http://192.168.1.8:5000 來進行訪問。
Flask從入門到入土(二)——請求响应與Flask扩展的更多相关文章
- Flask從入門到入土(三)——模板
模板是一個包含響應文本的文件,其中包含佔位變量表示的動態部分,其具體值只是請求上下文中才能知道.使用真實值替換變量,再返回最終得到的響應字符串,這一過程稱爲渲染.爲了渲染模板,Flask使用了一個名爲 ...
- Flask從入門到入土(三)——Web表單
Flask-WTF擴展可以把處理Web表單的過程變成一種愉悅的體驗.這個擴展對獨立的WTForms包進行了包裝,方便集成到Flask程序中. Flask-WTF及其依賴可使用pip安裝: pip in ...
- Flask從入門到入土(一)——程序的基本結構
一.初始化 所有Flask程序都必須創建一個程序實例.Web服務器使用一種名爲Web服務器網關接口的協議,把接收自客戶端的所有請求都轉交給這個對象處理.程序實例書Flask類的對象,創建代碼: fro ...
- Flask從入門到入土(四)——登錄實現
表單介紹 1.表單標籤 聲明表單的範圍,位於表單標籤中的元素將被提交 語法: <form> </form> 屬性: Method(提交方式get,post) , Enctyp ...
- Flask從入門到入土(五)——Flask与数据库
import sqlite3 def init_db(): sql = 'create table user(id INT,name TEXT)' conn = sqlite3.connect(&qu ...
- GOOGLE搜索從入門到精通V4.0
1,前言2,摘要3,如何使用本文4,Google簡介5,搜索入門6,初階搜索 6.1,搜索結果要求包含兩個及兩個以上關鍵字 6.2,搜索結果要求不包含某些特定資訊 6.3,搜索結果至少包含多個關鍵字中 ...
- 依賴注入入門——Unity(二)
參考博客文章http://www.cnblogs.com/kebixisimba/category/130432.html http://www.cnblogs.com/qqlin/tag/Unity ...
- Delphi APP 開發入門(二)Android/iOS設定,Hello World
Delphi APP 開發入門(二)Android/iOS設定,Hello World 分享: Share on facebookShare on twitterShare on google_plu ...
- Delphi APP 開發入門(一)重生的 Delphi
Delphi APP 開發入門(一)重生的 Delphi 分享: Share on facebookShare on twitterShare on google_plusone_share 閲讀 ...
随机推荐
- iterator_category
/* * 迭代器类型 * 1. input ierator * 2. write iterator * 3. forward iterator 在迭代器所形成的区间上进行读写操作 * 4. bidir ...
- CDuiString和String的转换
很多时候 难免用到CDuiString和string的转换. 我们应该注意到,CDuiString类有个方法: LPCTSTR GetData() const; 可以通过这个方法,把CDuiStrin ...
- Linkin大话eclipse快捷键
刚来这家公司的时候,作为菜鸟的我在帮别人调试代码的时候,有人说我快捷键使用的很熟悉. 呵呵,工欲善其事必先利其器,以下这些快捷键是最常用的也是要必须记住的. [Ctrl开头] Ctrl+1:快速修复 ...
- win7下JAVA环境变量配置方法
1.首先,根据自己的需要下载1.6或者1.7的JDK,安装JDK.(安装的时候记一下安装目录,后面会用到) 2.右键计算机→属性→高级系统设置→高级→环境变量,在系统变量部分新建名为"JAV ...
- wamp图标为黄色(非端口号问题)
1.Win键+R 输入:services.msc 进入服务,找到wamp,看哪个服务没有启动 2.手动启动apache服务失败,弹出以下错误 3.然后在cmd命令行中切换到你的apache的bin目 ...
- Java NIO之网络编程
最近在研究Java NIO和netty,曾经一度感觉很吃力,根本原因还是对操作系统.TCP/IP.socket编程的理解不到位. 不禁感叹,还是当初逃的课太多. 假如上天给我一次机会,能够再回到意气风 ...
- C#在winform中读写ini文件
class WY_INI { static string IniFileName; static char[] TrimChar = { ' ', '\t' }; public string[] Ge ...
- spring实例化bean三种方式
我看了这篇博文<https://www.cnblogs.com/zhanglei93/p/6221546.html>,以及自己实践总结了关于spring实例化bean对象的3种方式. 一. ...
- 23_迭代器、模拟For循环
一.可迭代对象 和 迭代器 1.可迭代对象和迭代器 可迭代对象:可以直接作用于for循环的对象统称为可迭代对象,Iterable. 迭代器:可以被next()函数调用并不断返回下一个值的对象称为迭代器 ...
- [Sdoi2017]硬币游戏 [高斯消元 KMP]
[Sdoi2017]硬币游戏 题意:硬币序列,H T等概率出现,\(n \le 300\)个人猜了一个长为$ m \le 300$的字符串,出现即获胜游戏结束.求每个人获胜概率 考场用了[1444: ...