2012-11-24 38 views
4

我在學習Backbone.js和Flask(和Flask-sqlalchemy)。我選擇Flask是因爲我認爲它與實現RESTful接口的Backbone完美結合。我目前正在以下使用(或多或少)這個模型courseFlask中的RESTful接口和序列化問題

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發送到瀏覽器中添加json_dump方法。否則,我會得到像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,但這些對我來說看起來相當複雜。

感謝

回答

7

我會用一個模塊來做到這一點,老實說。我們使用燒瓶安定一些的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增加了一些更好的反省技巧:

SQLAlchemy introspection

+0

對不起,遲到的迴應。是的,我認爲你參考的項目與我想到的是一樣的。順便說一下,我正在使用flask-sqlalchemy,所以我不知道sqlalchemy的內省應該怎麼做。我想我可以使用第一個選項,但我期待別的東西。 –

+0

這絕對不適合嬌氣,但它很強大。你可以在Flask-SQLAlchemy中使用這個方法,事實上,我給出的例子使用Flask-SQLAlchemy。我用它在我們的應用程序中進行自定義數據提取和其他深奧的魔法。 –

+0

好,我會盡力實現它。你知道這些老式方法是否除了管理請求和設置路由之外還有其他的工作,或者基本上就是這樣。 –

-1

瓶提供jsonify功能來做到這一點。檢查其工作here

你的json_dump方法是正確的,儘管代碼可以做得簡潔。看到這個代碼片段

@app.route('/tasks') 
def tasks(): 
    tasks = Tasks.query.all() 
    return jsonify(data=[c.json_dump() for c in tasks]) 
+0

但僅適用於某些對象。在這種情況下,它不是「開箱即用」的。看到這個http://stackoverflow.com/questions/7102754/jsonify-a-sqlalchemy-result-set-in-flask。提出的解決方案太複雜了。 –