Flask的url_for函數

序言

在學習Miguel Grinberg的“使用 Python 和 Flask 設計 RESTful API”一文中,在“優化web service接口”一節中,遇見flask的url_for函數,當時不解其意,查閱資料後,記錄,以便學習。

正文

原文中的API會讓客戶端在任務標識返回後去構造 URIs。這對於服務器十分簡單,但作者打算不直接返回任務的 ids,而是直接返回控制這些任務的完整的 URI,以便客戶端可以隨時使用這些 URIs。
在這裏作者構造了一個輔助函數生成一個 “公共” 版本任務發送到客戶端。

from flask import url_for

def make_public_task(task):
    new_task = {}
    for field in task:
        if field == 'id':
            new_task['uri'] = url_for('get_task', task_id=task['id'], _external=True)
        else:
            new_task[field] = task[field]
    return new_task

這裏做的事是從數據庫中取出任務並且創建一個新的任務,這個任務的 id 字段被替換成通過 Flask 的 url_for 生成的 uri 字段。當返回所有的任務列表的時候,在發送到客戶端之前會通過這個函數進行處理。

以下是通過GET方法查詢所有任務的代碼。

@app.route('/todo/api/v1.0/tasks', methods=['GET'])
def get_tasks():
    return jsonify({'tasks': map(make_public_task, tasks)})

在這裏貼上作者在url_for中使用的“get_task”代碼。

@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['GET'])
def get_task(task_id):
    task = filter(lambda t: t['id'] == task_id, tasks)
    if len(task) == 0:
        abort(404)
    return jsonify({'task': task[0]})

以下是從客戶端獲取任務列表時候得到的數據。

$ curl -i http://localhost:5000/todo/api/v1.0/tasks
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 406
Server: Werkzeug/0.8.3 Python/2.7.3
Date: Mon, 20 May 2013 18:16:28 GMT

{
  "tasks": [
    {
      "title": "Buy groceries",
      "done": false,
      "description": "Milk, Cheese, Pizza, Fruit, Tylenol",
      "uri": "http://localhost:5000/todo/api/v1.0/tasks/1"
    },
    {
      "title": "Learn Python",
      "done": false,
      "description": "Need to find a good Python tutorial on the web",
      "uri": "http://localhost:5000/todo/api/v1.0/tasks/2"
    }
  ]
}

然後我們來講講url_for函數。
url_for(endpoint, **values)接收這些參數,使用所提供的方法生成給定端點的URL。例如,最簡單的

#!flask/bin/python
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return "Hello, World!"

if __name__ == '__main__':
    app.run(debug=True)

當在程序中調用url_for(‘index’),則會返回/
如果調用url_for(‘index’, _external=True) 返回的則是絕對地址,在這個示例中是http://localhost:5000/
現在上面的url_for(‘get_task’, task_id=task[‘id’], _external=True)就好理解了,從get_task這個函數中獲取到絕對地址,把獲取到的task[‘id’]的值賦值給 task_id,從而得到了tasks中的字典的新鍵值對”uri”: “http://localhost:5000/todo/api/v1.0/tasks/1“。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章