我正在学习Backbone.js和Flask(以及Flask-sqlalchemy)。我之所以选择Flask,是因为我读到它与Backbone实现RESTful接口的效果很好。我目前正在关注使用(或多或少)此模型的course:
class Tasks(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80), unique=True)
completed = db.Column(db.Boolean, unique=False, default=False)
def __init__(self, title, completed):
self.title = title
self.completed = completed
def json_dump(self):
return dict(title=self.title, completed=self.completed)
def __repr__(self):
return '<Task %r>' % self.title
我必须添加json_dump
方法才能将JSON发送到浏览器。否则,我会收到object is not JSON serializable
之类的错误,所以我的第一个问题是:
有没有更好的方法在Flask中进行序列化?似乎某些对象是可序列化的,但其他对象不是,但一般来说,它并不像我预期的那么容易。
过了一会儿,我最终得到了以下观点来处理每种类型的请求:
@app.route('/tasks')
def tasks():
tasks = Tasks.query.all()
serialized = json.dumps([c.json_dump() for c in tasks])
return serialized
@app.route('/tasks/<id>', methods=['GET'])
def get_task(id):
tasks = Tasks.query.get(int(id))
serialized = json.dumps(tasks.json_dump())
return serialized
@app.route('/tasks/<id>', methods=['PUT'])
def put_task(id):
task = Tasks.query.get(int(id))
task.title = request.json['title']
task.completed = request.json['completed']
db.session.add(task)
db.session.commit()
serialized = json.dumps(task.json_dump())
return serialized
@app.route('/tasks/<id>', methods=['DELETE'])
def delete_task(id):
task = Tasks.query.get(int(id))
db.session.delete(task)
db.session.commit()
serialized = json.dumps(task.json_dump())
return serialized
@app.route('/tasks', methods=['POST'])
def post_task():
task = Tasks(request.json['title'], request.json['completed'])
db.session.add(task)
db.session.commit()
serialized = json.dumps(task.json_dump())
return serialized
在我看来,它似乎有点冗长。再次,实施它们的正确方法是什么?我见过一些在Flask中提供RESTful接口的extensions,但对我来说这看起来很复杂。
由于
答案 0 :(得分:8)
老实说,我会用一个模块来做这件事。我们已经将Flask-Restless用于某些API,你可能会看一下:
https://flask-restless.readthedocs.org/en/latest/
但是,如果要构建自己的构建,可以使用SQLAlchemy的内省将对象输出为键/值对。
http://docs.sqlalchemy.org/en/rel_0_7/core/schema.html#metadata-reflection
像这样的东西,虽然我总是要三重检查我的语法是正确的,所以把它作为指导而不是工作代码。
@app.route('/tasks')
def tasks():
tasks = Tasks.query.all()
output = []
for task in tasks:
row = {}
for field in Tasks.__table__.c:
row[str(field)] = getattr(task, field, None)
output.append(row)
return jsonify(data=output)
我发现这个问题可能对你有所帮助。我熟悉SQLAlchemy 0.7,看起来像0.8增加了一些更好的内省技术:
答案 1 :(得分:-1)
Flask提供jsonify
功能来执行此操作。查看其工作here。
你的json_dump方法是正确的,虽然代码可以简洁。请参阅此代码段
@app.route('/tasks')
def tasks():
tasks = Tasks.query.all()
return jsonify(data=[c.json_dump() for c in tasks])