Flask Rest API

通過 Flask Restful Api 對model進行CRUD (create,read,update,delete)

開始

源代碼 here

$ git clone https://github.com/rahmanfadhil/flask-rest-api.git

創(chuàng)建venv,安裝依賴

$ python -m venv env
$ source env/bin/activate
(env) $ pip install -r requirements.txt

依賴

step1

$ python3 -m venv env
$ source env/bin/activate
$ pip install Flask \
    Flask-SQLAlchemy \
    Flask-RESTful \
    flask-marshmallow

創(chuàng)建主函數(shù) main.py

from flask import Flask

app = Flask(__name__)

if __name__ == '__main__':
    app.run(debug=True)

測試一下

(env) $ python main.py

Open http://localhost:5000, and you will see a 404 page.

數(shù)據(jù)庫

這里選用sqlite,記得生產(chǎn)用postsql或mysql

from flask import Flask
from flask_sqlalchemy import SQLAlchemy # new

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db' # new
db = SQLAlchemy(app) # new

if __name__ == '__main__':
    app.run(debug=True)

Database model

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(50))
    content = db.Column(db.String(255))

    def __repr__(self): # str(post) 時會調(diào)用漓摩,即print時顯示的string
        return '<Post %s>' % self.title

在restful api中返回的數(shù)據(jù)是json格式肢执,所以需要把model轉(zhuǎn)換為json扩灯,這就需要
flask_marshmallow 晕换,先定義schema学少,再通過schema轉(zhuǎn)化為json

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow # new

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)
ma = Marshmallow(app) # new

# ...

if __name__ == '__main__':
    app.run(debug=True)

定義了兩個schema實例

class PostSchema(ma.Schema):
    class Meta:
        fields = ("id", "title", "content")

post_schema = PostSchema()
posts_schema = PostSchema(many=True)

初始化數(shù)據(jù)庫,當然也可以使用flask migrate鳞疲,這里使用最簡單的方式罪郊。

(env) $ python
>>> from main import db
>>> db.create_all()
>>> exit()

RESTful 路由

Get Posts api

class PostListResource(Resource):
    def get(self):
        posts = Post.query.all()
        return posts_schema.dump(posts) # schema 作用就是將posts轉(zhuǎn)為dict

api.add_resource(PostListResource, '/posts') # 綁定了路由

測試

$ curl http://localhost:5000/posts
[]

Create Api

# ...
from flask import Flask, request # change

# ...

class PostListResource(Resource):
    def get(self):
        posts = Post.query.all()
        return posts_schema.dump(posts)

    # create api
    def post(self):
        new_post = Post(
            title=request.json['title'],
            content=request.json['content']
        )
        db.session.add(new_post)
        db.session.commit()
        return post_schema.dump(new_post)

# ...

測試

$ curl http://localhost:5000/posts \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"title":"Post 1", "content":"Lorem ipsum"}'
{
    "content": "Lorem ipsum",
    "id": 1,
    "title": "Post 1"
}

根據(jù)id獲取post,get_or_404: 在獲取不到時尚洽,返回404

class PostResource(Resource):
    def get(self, post_id):
        post = Post.query.get_or_404(post_id)
        return post_schema.dump(post)

api.add_resource(PostResource, '/posts/<int:post_id>')

測試1

$ curl http://localhost:5000/posts/1
{
    "title": "Post 1",
    "content": "Lorem ipsum",
    "id": 1
}

測試2

$ curl http://localhost:5000/posts/12 -I
HTTP/1.0 404 NOT FOUND
...

新增 update和delete

class PostResource(Resource):
    # ...

    def patch(self, post_id):
        post = Post.query.get_or_404(post_id)

        if 'title' in request.json:
            post.title = request.json['title']
        if 'content' in request.json:
            post.content = request.json['content']

        db.session.commit()
        return post_schema.dump(post)

    def delete(self, post_id):
        post = Post.query.get_or_404(post_id)
        post.delete()
        db.session.commit()
        return '', 204

測試 Update :

$ curl http://localhost:5000/posts/1 \
    -X PATCH \
    -H "Content-Type: application/json" \
    -d '{"title":"Updated Post", "content":"Updated post content"}'
{
    "content": "Updated post content",
    "id": 1,
    "title": "Updated Post"
}

** 測試 Delete :**

$ curl http://localhost:5000/posts/1 -X DELETE -I
HTTP/1.0 204 NO CONTENT
...
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末悔橄,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子腺毫,更是在濱河造成了極大的恐慌癣疟,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件潮酒,死亡現(xiàn)場離奇詭異睛挚,居然都是意外死亡,警方通過查閱死者的電腦和手機急黎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門扎狱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人勃教,你說我怎么就攤上這事淤击。” “怎么了故源?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵污抬,是天一觀的道長。 經(jīng)常有香客問我绳军,道長壕吹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任删铃,我火速辦了婚禮,結(jié)果婚禮上踏堡,老公的妹妹穿的比我還像新娘猎唁。我一直安慰自己,他們只是感情好顷蟆,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布诫隅。 她就那樣靜靜地躺著,像睡著了一般帐偎。 火紅的嫁衣襯著肌膚如雪逐纬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天削樊,我揣著相機與錄音豁生,去河邊找鬼兔毒。 笑死,一個胖子當著我的面吹牛甸箱,可吹牛的內(nèi)容都是我干的育叁。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼芍殖,長吁一口氣:“原來是場噩夢啊……” “哼豪嗽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起豌骏,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎窃躲,沒想到半個月后计贰,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡框舔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了福贞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡拇舀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出要拂,到底是詐尸還是另有隱情,我是刑警寧澤窿春,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布纽甘,位于F島的核電站,受9級特大地震影響左权,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赏迟,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一泻仙、第九天 我趴在偏房一處隱蔽的房頂上張望突想。 院中可真熱鬧,春花似錦绑嘹、人聲如沸圾叼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至一膨,卻和暖如春价淌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工僧家, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人似嗤。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓烁落,卻偏偏與公主長得像,于是被迫代替她去往敵國和親旦棉。 傳聞我的和親對象是個殘疾皇子童本,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容