2013-11-22 19 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或您教其做的任何其他事情。 –