python - Flask-restful:将复杂对象编码为 json

标签 python json rest flask flask-restful

我有一个关于 flask restful 扩展的问题。我刚开始使用它并遇到了一个问题。我有连接多对一关系的 flask-sqlalchemy 实体,我希望使用编码器在 json 中那个 restful 端点返回父实体及其所有子实体。在我的例子中,Set 包含许多参数。我看着 flask-restful docs但没有任何解释如何解决这个案子。

似乎我遗漏了一些明显的东西,但无法找到任何解决方案。 这是我的代码:

# entities
class Set(db.Model):
    id = db.Column("id", db.Integer, db.Sequence("set_id_seq"), primary_key=True)
    title = db.Column("title", db.String(256))

    parameters = db.relationship("Parameters", backref="set", cascade="all")


class Parameters(db.Model):
    id = db.Column("id", db.Integer, db.Sequence("parameter_id_seq"), primary_key=True)
    flag = db.Column("flag", db.String(256))
    value = db.Column("value", db.String(256))
    set_id = db.Column("set_id", db.Integer, db.ForeignKey("set.id"))


# marshallers

from flask.ext.restful import fields

parameter_marshaller = {
    "flag": fields.String,
    "value": fields.String
}

set_marshaller = {
    'id': fields.String,
    'title': fields.String,
    'parameters': fields.List(fields.Nested(parameter_marshaller))
}

# endpoint    

class SetApi(Resource):

    @marshal_with(marshallers.set_marshaller)
    def get(self, set_id):
        entity = Set.query.get(set_id)
        return entity


restful_api = Api(app)
restful_api.add_resource(SetApi, "/api/set/<int:set_id>")

现在,当我调用 /api/set/1 时,出现服务器错误:

TypeError: 'Set' 对象不可订阅

所以我需要一种方法来正确定义端点返回此 json 的 set_marshaller:

{
  "id": : "1",
  "title": "any-title",
  "parameters": [
       {"flag": "any-flag", "value": "any-value" },
       {"flag": "any-flag", "value": "any-value" },
       .....
   ]
}

感谢任何帮助。

最佳答案

我自己找到了解决该问题的方法。

在玩过 flask-restful 之后,我发现我犯了一些错误:

首先 set_marshaller 应该是这样的:

set_marshaller = {
    'id': fields.String,
    'title': fields.String,
    'parameters': fields.Nested(parameter_marshaller)
}

ReSTLess marshaller 可以处理参数为列表的情况,并将其编码为 json 列表。

另一个问题是 API 中的 Set 参数具有延迟加载,因此当我尝试编码 Set 时出现 KeyError: 'parameters',因此我需要像这样显式加载参数:

class SetApi(Resource):

     @marshal_with(marshallers.set_marshaller)
     def get(self, set_id):
        entity = Set.query.get(set_id)
        entity.parameters # loads parameters from db
        return entity

或者另一种选择是改变模型关系:

parameters = db.relationship("Parameters", backref="set", cascade="all" lazy="joined")

关于python - Flask-restful:将复杂对象编码为 json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22035974/

相关文章:

python - 日志记录和 Python Bokeh 兼容性

javascript - JSON 数据未显示在 Plunker 中

Python内存序列化

python - 使用多个输入提供 keras 模型

python - 传递自类参数 python

json - 像javascript中的Stringify一样构造成json

javascript - 对服务器返回的 json 对象的 Crossdomian ajax 请求显示错误 Unexpected token :

asp.net - 寻找 RESTful API 的身份验证/模拟策略

java - 通过查询字符串的 REST api

java - 如何通过 REST API 关联两个实体