首頁  >  文章  >  後端開發  >  Python開發WEB框架Flask詳細介紹

Python開發WEB框架Flask詳細介紹

高洛峰
高洛峰原創
2017-03-19 17:05:402353瀏覽

Flask簡介

Flask是相對於Django而言輕量級的Web框架

和Django大包大攬不同,Flask建立於一系列的開源軟體包之上,這其中最主要的是WSGI應用開發庫Werkzeug和模板引擎Jinja:

策略:werkzeug和Jinja這兩個函式庫和Flask一樣,都是pocoo團隊開發的。這 或許體現了pocoo與Django競爭時關於生態的一種策略,這種策略的自然 延伸是Flask框架中沒有包含資料庫方面的構件,無論ORM還是其他。

重點:Flask是一個WSGI應用框架,這表示我們進行Flask開發時,不需要專注於網路方面的操作,Flask應用程式的入口是封裝過的網路請求包,出口是網路回應,我們只需要關注這個階段內的處理邏輯。

WSGI伺服器 :Flask雖然內建了簡單的WSGI伺服器,但其效能僅適用於開發期間的偵錯。 Flask官網推薦了多種WSGI伺服器,實作方式從多進程到多執行緒到協程, 這方面的選擇我們在本課程中將不涉及。

REST適應性 :雖然Flask和Django一樣,最初的出發點都是服務端的動態網頁應用程式。但Flask的設計使其也相當適用於資源導向的REST架構,在越來越行動化且單頁應用越來越重要的WEB開發領域,這是Flask相對於Django相當大的優勢。

Hello Flask

寫一個基於Flask的hello world相當容易:

1、導入Flask類

from flask import Flask

Flask類是Flask框架的核心類,它實作了WSGI應用規範。

2、建立Flask實例

app = Flask(name)

Flask建構子的第一個參數指定一個引入名/importname。 Flask框架 使用這個名字進行靜態資源、模板、錯誤訊息的定位。除非你清楚的理解它的 作用,通常情況下,我們總是應該使用特殊變數_name。

Flask實例是可呼叫的(具有call方法),這個實例可以直接對接 WSGI伺服器。

3、註冊路由

@route('/')
def index():
    return 'Hello,Flask!'

註冊路由就是建立URL規則和處理函數之間的關聯。 Flask框架依賴路由 完成HTTP請求的分發。

路由中的函數稱為視圖函數,其傳回值將作為HTTP回應的正文內容。

4、對接並啟動WSGI伺服器

Flask封裝了一個簡單的開發用WSGI伺服器,我們可以透過呼叫run() 啟動伺服器來執行:

app.run(host='0.0.0.0',port=80)

概述

路由是MVC架構的Web框架中相當重要的概念,也是本課程的重點。

顧名思意,路由就是在迷茫中找出一條路的意思。在Flask框架中,路由就表示為使用者請求的URL找出其對應的處理函數之意。

在本節課程,我們將主要從以下幾個面向來講解Flask框架中的路由:

如何為應用程式註冊路由? 如何為路由指定其支援的HTTP方法? 如何匹配動態URL? 如何對URL中的變數類型進行篩選? 如何理解訪問點/endpoint? 如何為應用程式設定靜態路由? 如何避免硬編碼指向其他視圖的URL?

註冊路由

在Flask應用程式中,路由是指使用者請求的URL與視圖函數之間的對應。 Flask框架根據HTTP請求的URL在路由表中匹配預先定義的URL規則,找到對應的視圖函數, 並將視圖函數的執行結果傳回WSGI伺服器:

Python開發WEB框架Flask詳細介紹

可見路由表在Flask應用中處於相當核心的位置。路由表的內容是由應用程式開發者填入。

route裝飾器 :可以使用Flask應用實例的route裝飾器將一個URL規則綁定到 一個視圖函數上。

例如,下面的範例將URL規則/test綁定到視圖函數test()上:

@app.route('/test')
def test():
    return 'this is response'

如果這個應用程式部署在主機ezhost.com的根目錄下,那麼當用戶訪問:

http://pythontab.com/teset

Flask框架就會呼叫我們的test()函數,其回傳結果就會傳遞給WSGI伺服器傳送給訪客。

add_url_rule() :另一個等價的寫法是使用Flask應用實例的add_url_route()方法。 下面的範例註冊了一個與前例相同的路由:

def test():
    return 'this is response'
app.add_url_route('/test',view_func=test)

其實,route裝飾器內部也是透過呼叫add_url_route()方法實現的路由註冊。 但顯然,使用裝飾器使程式碼看起來更優雅一些。

为路由指定HTTP方法

默认情况下,Flask路由仅支持HTTP的GET请求。可以使用methods关键字参数,在注册 路由时显式地声明视图方法支持的HTTP方法。

例如,下面的示例将URL规则/auth绑定到视图函数v_auth(),这个路由仅支持POST方法:

@app.route('/auth',methods=['POST'])
def v_auth():pass

指定多种HTTP方法支持

关键字参数methods的类型为list,因此可以同时指定多种HTTP方法。

下面的示例中,使URL规则/user同时支持POST方法和GET方法:

@app.route('/user',methods=['POST','GET'])
def v_users():
    if request.method == 'GET':
        return ... # 返回用户列表
    if request.method == 'POST'
        return ... #创建新用户

这个特性使Flask非常易于开发REST架构的后台服务,而不仅仅局限于传统的动态网页。

匹配动态URL

有时我们需要将同一类URL映射到同一个视图函数处理,比如,使用同一个视图函数 来显示不同用户的个人档案。我们希望以下的URL都可以分发到同一个视图函数:

Python開發WEB框架Flask詳細介紹

在Flask中,可以将URL中的可变部分使用一对小括号声明为变量, 并为视图函数声明同名的参数:

@app.route('/user/')
def v_user(uname):
    return '%s\'s Profile' % uname

在上面的示例中,URL规则中的

URL变量类型过滤

考虑下面的示例,我们希望通过HTTP共享文件夹/var/readonly中的文件:

/var

    /readonly

        /a.txt

        /b.txt

        /repo

           /c.txt

           /d.txt

简单思考一下就有答案了。我们可以构造URL规则/file/

@app.route('/file/')
def v_file(fname):
    fullname = os.path.join('/var/readonly',fname)
    f = open(fullname)
    cnt =  f.read()
    f.close()
    return cnt

测试结果表明,/file/a.txt和/file/b.txt都没有问题,但是/file/repo/c.txt和 /file/repo/d.txt却会失败。

这是因为,默认情况下,在URL规则中的变量被视为不包含/的字符串。/file/repo/c.txt 是没有办法匹配URL规则/file/

可以使用内置的path转换器告诉Flask框架改变这一默认行为。path转换器允许 规则匹配包含/的字符串:

@app.route('/file/')

在Flask中,转换器/converter用来对从URL中提取的变量进行预处理,这个过程 发生在调用视图函数之前。Flask预置了四种转换器:

string - 匹配不包含/的字符串,这是默认的转换器

path - 匹配包含/的字符串

int - 只有当URL中的变量是整型值时才匹配,并将变量转换为整型

float - 只有当URL中的变量是浮点值时才匹配,并将变量转换为浮点型

访问点/endpoint

我们一直强调,路由的作用是根据请求的URL,找到对应的视图函数。这没错,但是在 Flask框架中,请求任务的分发并不是直接从用户请求的URL一步定位到视图函数, 两者之间隔着一个访问点/endpoint。

以下面的代码为例,我们看Flask怎样实现请求的分发:

@app.route('/home')
def home():pass

在Flask内部使用两张表维护路由:

url_map :维护URL规则和endpoint的映射

view_functions :维护endpoint和视图函数的映射。

以用户访问URL/home为例,Flask将首先利用url_map找到所请求URL对应的 endpoint,即访问点home,然后再利用view_functions表查找home这个访问点 对应的视图函数,最终匹配到函数home():

Python開發WEB框架Flask詳細介紹

默认访问点 :当我们使用route装饰器注册路由时,默认使用被装饰函数的 函数名(name)作为访问点,因此,你看到上面的表中,路由中的访问点为home。

自定义访问点 :可以在使用route装饰器或调用add_url_rule()方法注册路由时,使用 endpoint关键字参数改变这一默认行为:

@app.route('/home',endpoint='whocare')
def home():pass

此时的两张路由表将变成这样:

Python開發WEB框架Flask詳細介紹

静态目录路由

当创建应用实例时,Flask将自动添加一条静态目录路由,其访问点 始终被设置为static,URL规则默认被设置为/static,本地路径默认被 设置为应用文件夹下的static子文件夹:

+------------------------------------------------------------+ | url rule | endpoint | view_function | | /static | static | Flask.send_static_file | +------------------------------------------------------------+ 如果你的应用目录如下:

/app

    /web.py

    /static

        /main.css

        /jquery.min.js   

那么启动应用后就可以通过URL/static/main.css访问static文件夹下的main.css了。

除了访问点被固定为static,静态目录的URL规则和本地目录都是可以根据应用情况进行调整。

改变默认的本地路径 :可以在创建应用对象时使用关键字参数static_folder改变 默认的静态文件夹。例如,你的静态文件都存放在应用下的assets目录下, 那么可以按如下的方式创建应用对象:

app = Flask(name,static_folder='assets') 也可以使用一个绝对路径:

app = Flask(name,static_folder='/var/www/static') 改变默认的本地路径并不会对路由表产生影响。

改变默认的URL规则 : 如果不喜欢静态目录URL/static,也可以在创建应用 对象时使用关键字参数static_url_path换一个别的名字。

下面的示例中,将应用下的assets文件夹注册为静态目录/assets:

app = Flask(name,static_folder='assets',static_url_path='/assets') 当应用运行后,通过URL/assets/main.css就可以访问assets文件夹下的 main.css文件了。

这时的路由表变化为:

+------------------------------------------------------------+ | url | endpoint | view_function | | /assets | static | Flask.send_static_file | +------------------------------------------------------------+

构造URL

在一个实用的视图中,不可避免地存在指向其他视图的链接。在之前的课程示例中,我们 都是在视图函数中这样硬编码这些链接URL的:

@app.route('/')
def v_index():
    return 'tech'
@app.route('/tech') 
def v_tech():pass

大部分情况下这种硬编码URL是可以工作的。但如果这个应用被挂在WSGI服务器的一个 子路径下,比如:/app1,那么用户访问URL/tech是不会成功的,这时应当访问/app1/tech 才可以正确地路由到视图函数v_tech()。

我们应当使用访问点让Flask框架帮我们计算链接URL。简单地给url_for()函数传入 一个访问点,它返回将是一个可靠的URL地址:

@app.route('/')
def v_index():
    print url_for('v_contacts')  # /contact
    return 'see console output!'
@app.route('/contact')
def v_contacts():pass

添加查询参数 : 使用关键字参数,可以在构造的URL中生成查询串。下面的调用将生成 /contact?

format=json
@app.route('/')
def v_index():
    print url_for('v_contacts',format='json')
    return  ''
@app.route('/contact')     
def v_contacts():pass

添加URL变量 : 如果指定访问点对应的视图函数接收参数,那么关键字参数将生成对应的参数URL。下面的 示例将生成/contact/Julia?format=html:

@app.route('/')
def v_index():
    print url_for('v_contact',name='Julia',format='html')
    return ''
@app.route('/contact/')
def v_contact(name):pass

添加锚点 :使用_anchor关键字可以为生成的URL添加锚点。下面的示例将生成URL /contact#part2

@app.route('/')
def v_index():
    print url_for('v_contacts',_anchor='part2')
@app.route('/contact')
def v_contacts():pass

外部URL : 默认情况下,url_for()生成站内URL,可以设置关键字参数_external 为True,生成包含站点地址的外部URL。下面的示例将生成URLhttp://

@app.route('/')
def v_index():
    print url_for('v_contacts',_external=True)
@app.route('/contact')
def v_contacts():pass

以上是Python開發WEB框架Flask詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn