2013-11-22 86 views
6

在flask-restful上嘗試新的CORS特性時,我發現裝飾器只能在函數返回字符串時應用。CORE上的TypeError讓燒瓶寧靜

例如,修改Quickstart example

class HelloWorld(restful.Resource): 
    @cors.crossdomain(origin='*') 
    def get(self): 
     return {'hello': 'world'} 

拋出:

TypeError: 'dict' object is not callable

難道我做錯了什麼?

回答

4

我最近自己遇到了這個問題。 @MartijnPieters是正確的,decorators不能在視圖的單個方法上調用。

我創建了一個包含 decorator列表的抽象基類。消耗 Resource(來自flask-restful)的類也繼承了基類,該類是實際將裝飾列表應用於視圖的類。

class AbstractAPI(): 
     decorators = [cors.crossdomain(origin='*')] 

    class HelloWorld(restful.Resource, AbstractAPI): 
     #content 

都能跟得上。

只是裝飾列表添加到參數創建API實例

api = Api(app) 
api.decorators=[cors.crossdomain(origin='*')] 
+0

這個作品,謝謝! – user3022063

+0

此外,添加'from flask_restful.utils import cors' – JeffD23

0

包裝函數的返回值作爲一個參數傳遞給flask.make_response();任何一個正常瓶視圖可以返回是可以接受的。裝飾器基本上與this Flask snippet相同。

由於瓶的RESTful Resourceflask.views.MethodView一個子類,你真的應該放裝飾直接在這裏的方法。作爲Decorating Views記錄你應該列出視圖裝修中一個特殊的類屬性,decorators這是一個列表:

class HelloWorld(restful.Resource): 
    decorators = [cors.crossdomain(origin='*')] 

    def get(self): 
     return {'hello': 'world'} 

和瓶將視圖適用於HelloWorld.as_view()返回的實際視圖的方法,這是什麼瓶實際上是調用時調度路線到視圖。

直接將其應用到方法只會服務器混淆restful.Resource調度程序,因爲它是期待方法返回的Python數據結構適合編碼JSON,這是不是有什麼cors.crossdomain()回報呢。

+3

使用'decorators'類變量我仍然得到相同的錯誤... – user3022063

+0

@ user3022063:真的嗎?這很好奇,因爲直到調用'HelloWorld.as_view()'這些函數纔會被應用,這意味着它們不會被應用到'get()',而是被應用到調度器,所以在**'restful.Resource之後'已將您的方法響應轉換爲JSON。 –

+0

事實上,這不是什麼情況,也許是因爲燒瓶寧靜的資源不是可插入的視圖,但有些不同。 – miracle2k

0

我發現,你仍然可以使用提供你返回一個字符串或JSON響應(這是一個可能是好的做法裝飾後API無論如何)。如果您想要執行特定於路由的CORS頭文件,使用裝飾器使生活變得更加簡單,這一點非常重要。看到這個合併拉REQ的詳細資料:https://github.com/flask-restful/flask-restful/pull/131

下面是一個例子:

from . import app 
from flask_restful import reqparse, abort, Api, Resource 
from flask.ext.cors import cross_origin 
from datetime import datetime 
from flask import jsonify 

api = Api(app) 


class DateTime(Resource): 
    @cross_origin(origins="http://localhost:63342*") 
    def get(self): 
     return jsonify({'DateTime': str(datetime.today())}) 

api_root = '/api/v1/' 
api.add_resource(DateTime, api_root + 'DateTime') 

如果你使用的瓶的安全性,添加auth裝飾在我的測試一些怪異的行爲。我建議使用assert current_user.is_authenticated。如果您允許憑據,請確保CSRF保護。

+0

使用Flask-Restful的整個*點*是使您的API *響應編碼不可知*。 Flask-Restful負責根據與客戶端的內容協商,將其編碼爲接受的響應編碼,例如XML,JSON或您教其做的任何其他事情。 –