2013-12-18 59 views
3

我有一个类看起来像下面:瓶jsonify:对象不是可迭代

class Sound(SoundJsonSerializer): 
    def __init__(self, name, length): 
     self.name = name 
     self.length = length 

其中SoundJsonSerializer使我的自定义JSONEncoder序列化此对象到JSON:

{ 
    "name": "foobar", 
    "length": 23.4 
} 

现在我想一个我的要求完全符合上述JSON的要求。

@app.route('/sounds/<soundid>') 
def get_sound(soundid): 
    s = Sound("foobar", 23.4) 
    return jsonify(s) 

产生一个错误声明s是不可迭代的,这是真的。如何让该方法返回我想要的JSON?

我知道我可以通过明确从我Sound对象创建的字典是这样做的:

return jsonify({"name": s.name, "length": s.length}) 

但这似乎真丑我。什么是实现我的目标的首选方式?

+0

其实,我宁愿你认为“丑”的方式。如果你经常这样做,那么可能将字典创建成一个函数,该函数接受对象和一系列表示你想要包含的属性(或者可能被排除)的字符串并创建字典(使用'dir()'和'getattr的()')。 –

+2

是的,这个问题很烦人,所以我决定[修补Flask使其工作](https://github.com/mitsuhiko/flask/pull/1209)。 –

回答

3

你可能围绕尝试这项工作:

class Sound(): 
    def __init__(self, name, length): 
     self.name = name 
     self.length = length 

@app.route('/sounds/<soundid>') 
def get_sound(soundid): 
    s = Sound('foobar', 23.4) 
    return jsonify(s.__dict__) 
+2

这不是一个好的做法,因为它暴露了所有的类内部结构,不仅仅是他想要的属性 –

+1

@PaoloCasciello是正确的,可能只有JSON表示中我想要的属性的子集。这就是我的自定义JSONEncoder照顾。 – rkcpi

2

你可以做这几个不同的方式。以确保您只返回你想要的最安全的办法是做这样的:

class Sound(): 
    name = None 
    length = None 
    test = "Test" 

    def __init__(self, name, length): 
     self.name = name 
     self.length = length 

@admin_app.route('/sounds/<sound_id>') 
def get_sound(sound_id): 
    s = Sound('foobar', sound_id) 
    return jsonify(vars(s)) 

通过定义名称=无,长度=无作为类级别变量的一部分,你可以使用瓦尔( )相对于__dict__

当你实例通过__init__类,并设置变量那里,jsonify将只返回您通过__init__设置什么。

结果与上面的代码:

{ 
"length": "1", 
"name": "foobar" 
}