目录

前文列表

用 Flask 来写个轻博客 (1) — 创建项目

用 Flask 来写个轻博客 (2) — Hello World!

用 Flask 来写个轻博客 (3) — (M)VC_连接 MySQL 和 SQLAlchemy

用 Flask 来写个轻博客 (4) — (M)VC_创建数据模型和表

用 Flask 来写个轻博客 (5) — (M)VC_SQLAlchemy 的 CRUD 详解

用 Flask 来写个轻博客 (6) — (M)VC_models 的关系(one to many)

用 Flask 来写个轻博客 (7) — (M)VC_models 的关系(many to many)

用 Flask 来写个轻博客 (8) — (M)VC_Alembic 管理数据库结构的升级和降级

用 Flask 来写个轻博客 (9) — M(V)C_Jinja 语法基础快速概览

用 Flask 来写个轻博客 (10) — M(V)C_Jinja 常用过滤器与 Flask 特殊变量及方法

用 Flask 来写个轻博客 (11) — M(V)C_创建视图函数

用 Flask 来写个轻博客 (12) — M(V)C_编写和继承 Jinja 模板

用 Flask 来写个轻博客 (13) — M(V)C_WTForms 服务端表单检验

用 Flask 来写个轻博客 (14) — M(V)C_实现项目首页的模板

用 Flask 来写个轻博客 (15) — M(V)C_实现博文页面评论表单

用 Flask 来写个轻博客 (16) — MV(C)_Flask Blueprint 蓝图

用 Flask 来写个轻博客 (17) — MV(C)_应用蓝图来重构项目

用 Flask 来写个轻博客 (18) — 使用工厂模式来生成应用对象

用 Flask 来写个轻博客 (19) — 以 Bcrypt 密文存储账户信息与实现用户登陆表单

用 Flask 来写个轻博客 (20) — 实现注册表单与应用 reCAPTCHA 来实现验证码

用 Flask 来写个轻博客 (21) — 结合 reCAPTCHA 验证码实现用户注册与登录

用 Flask 来写个轻博客 (22) — 实现博客文章的添加和编辑页面

用 Flask 来写个轻博客 (23) — 应用 OAuth 来实现 Facebook 第三方登录

用 Flask 来写个轻博客 (24) — 使用 Flask-Login 来保护应用安全

用 Flask 来写个轻博客 (25) — 使用 Flask-Principal 实现角色权限功能

用 Flask 来写个轻博客 (26) — 使用 Flask-Celery-Helper 实现异步任务

用 Flask 来写个轻博客 (27) — 使用 Flask-Cache 实现网页缓存加速

用 Flask 来写个轻博客 (29) — 使用 Flask-Admin 实现后台管理 SQLAlchemy

用 Flask 来写个轻博客 (30) — 使用 Flask-Admin 增强文章管理功能

用 Flask 来写个轻博客 (31) — 使用 Flask-Admin 实现 FileSystem 管理

用 Flask 来写个轻博客 (32) — 使用 Flask-RESTful 来构建 RESTful API 之一

用 Flask 来写个轻博客 (33) — 使用 Flask-RESTful 来构建 RESTful API 之二

用 Flask 来写个轻博客 (34) — 使用 Flask-RESTful 来构建 RESTful API 之三

用 Flask 来写个轻博客 (35) — 使用 Flask-RESTful 来构建 RESTful API 之四

PUT 请求

紧接前 4 篇, 继续完成 PUT 和 DELETE 请求的实现.

  • PUT 请求对应的是资源类的 put() 方法, 表示更新操作. 所以仍然需要先定义 post_put 解析器

    vim jmilkfansblog/controllers/flask_restful/parsers.py
post_put_parser = reqparse.RequestParser()

post_put_parser.add_argument(
'title',
type=str) post_put_parser.add_argument(
'text',
type=str) post_put_parser.add_argument(
'tags',
type=str,
action='append') post_put_parser.add_argument(
'token',
type=str,
required=True,
help='Auth Token is required to update the posts.')

NOTE: 从 post_put_parser 解析器可以看见, 我们仅允许传入最多 4 个参数, 其中也一定不能缺少 token 以保证数据的安全性.

  • 定义资源类 PostApi 的 put() 更新方法

    vim jmilkfansblog/controllers/flask_restful/posts.py
...

    def put(self, post_id=None):
"""Will be execute when receive the HTTP Request Methos `PUT`.""" if not post_id:
abort(400) post = Post.query.filter_by(id=post_id).first()
if not post:
abort(404) args = parsers.post_put_parser.parse_args()
user = User.verify_auth_token(args['token']) if not user:
abort(401)
if user != post.user:
abort(403) if args['title']:
post.title = args['title']
if args['text']:
post.text = args['text']
if args['tags']:
for item in args['tags']:
tag = Tag.query.filter_by(name=item).first()
if tag:
post.tags.append(tag)
else:
new_tag = Tag()
new_tag.name = item
post.tags.append(new_tag) db.session.add(post)
db.session.commit() return (post.id, 201)
...

NOTE: put() 方法和 post() 方法很相似, 所以这里不在赘叙.

DELETE 请求

DELETE 请求的实现是最简单的, 一般而言, 不需要返回任何的数据, 只需要返回正确的 HTTP status_int 就可以了.

vim jmilkfansblog/controllers/flask_restful/posts.py

    def delete(self, post_id=None):
"""Will be execute when receive the HTTP Request Method `DELETE`.""" if not post_id:
abort(400) post = Post.query.filter_by(id=post_id).first()
if not post:
abort(404) args = parsers.post_delete_parser.parse_args(strict=True)
user = User.verify_auth_token(args['token'])
if user != post.user:
abort(403) # Will be delete relationship record with posts_tags too.
# But you have to ensure the number of record equal with len(post.tags)
db.session.delete(post)
db.session.commit() return "", 204

测试

对一条已经存在的 posts 记录进行 update 操作

mysql> select * from posts where id='1746b650-bcab-436b-82ab-7411e252b576';
+--------------------------------------+-----------+-------+--------------+--------------------------------------+
| id | title | text | publish_date | user_id |
+--------------------------------------+-----------+-------+--------------+--------------------------------------+
| 1746b650-bcab-436b-82ab-7411e252b576 | Just Test | Hello | NULL | 65cb9792-b876-49e7-b2c5-46468624199e |
+--------------------------------------+-----------+-------+--------------+--------------------------------------+
1 row in set (0.00 sec)
  • 获取 Token
jmilkfan@JmilkFan-Devstack:/opt/JmilkFan-s-Blog$ curl -d "username=<username>" -d "password=<password>" http://localhost:8089/api/auth
{
"token": "eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ4MzM2MjExNywiaWF0IjoxNDgzMzYxNTE3fQ.eyJpZCI6IjY1Y2I5NzkyLWI4NzYtNDllNy1iMmM1LTQ2NDY4NjI0MTk5ZSJ9.2r7f-SZJS2U8Zafqyl7oUYPfFGilDJemVwImPuIHxd0"
}
  • PUT 请求
jmilkfan@JmilkFan-Devstack:/opt/JmilkFan-s-Blog$ curl -X PUT -d "title=Just Test PUT" -d "text=Hello Guys" -d "tags=Python" -d "tags=Flask" -d "token=eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ4MzM2MjExNywiaWF0IjoxNDgzMzYxNTE3fQ.eyJpZCI6IjY1Y2I5NzkyLWI4NzYtNDllNy1iMmM1LTQ2NDY4NjI0MTk5ZSJ9.2r7f-SZJS2U8Zafqyl7oUYPfFGilDJemVwImPuIHxd0" http://localhost:8089/api/posts/1746b650-bcab-436b-82ab-7411e252b576
"1746b650-bcab-436b-82ab-7411e252b576"
  • 结果
mysql> select * from posts where id='1746b650-bcab-436b-82ab-7411e252b576';
+--------------------------------------+---------------+------------+--------------+--------------------------------------+
| id | title | text | publish_date | user_id |
+--------------------------------------+---------------+------------+--------------+--------------------------------------+
| 1746b650-bcab-436b-82ab-7411e252b576 | Just Test PUT | Hello Guys | NULL | 65cb9792-b876-49e7-b2c5-46468624199e |
+--------------------------------------+---------------+------------+--------------+--------------------------------------+
1 row in set (0.00 sec)

删除一条记录

jmilkfan@JmilkFan-Devstack:/opt/JmilkFan-s-Blog$ curl -X DELETE -d "token=eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ4MzM2MjkzMywiaWF0IjoxNDgzMzYyMzMzfQ.eyJpZCI6IjY1Y2I5NzkyLWI4NzYtNDllNy1iMmM1LTQ2NDY4NjI0MTk5ZSJ9.B8ISY5Fb6AD_PyrJxNVQNYuxXUMrEioB-rlhtyvYcxU" http://localhost:8089/api/posts/1746b650-bcab-436b-82ab-7411e252b576
  • 结果
mysql> select * from posts where id='1746b650-bcab-436b-82ab-7411e252b576';
Empty set (0.00 sec)

用 Flask 来写个轻博客 (36) — 使用 Flask-RESTful 来构建 RESTful API 之五的更多相关文章

  1. 用 Flask 来写个轻博客

    用 Flask 来写个轻博客 用 Flask 来写个轻博客 (1) — 创建项目 用 Flask 来写个轻博客 (2) — Hello World! 用 Flask 来写个轻博客 (3) — (M)V ...

  2. 用 Flask 来写个轻博客 (37) — 在 Github 上为第一阶段的版本打 Tag

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 第一阶段结语 打 Tag 前文列表 用 Flask 来写个轻博客 (1 ...

  3. 用 Flask 来写个轻博客 (35) — 使用 Flask-RESTful 来构建 RESTful API 之四

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 POST 请求 身份认证 测试 前文列表 用 Flask 来写个轻博客 ...

  4. 用 Flask 来写个轻博客 (34) — 使用 Flask-RESTful 来构建 RESTful API 之三

    目录 目录 前文列表 应用请求中的参数实现 API 分页 测试 前文列表 用 Flask 来写个轻博客 (1) - 创建项目 用 Flask 来写个轻博客 (2) - Hello World! 用 F ...

  5. 用 Flask 来写个轻博客 (33) — 使用 Flask-RESTful 来构建 RESTful API 之二

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 构建 RESTful Flask API 定义资源路由 格式 ...

  6. 用 Flask 来写个轻博客 (32) — 使用 Flask-RESTful 来构建 RESTful API 之一

    目录 目录 前文列表 扩展阅读 RESTful API REST 原则 无状态原则 面向资源 RESTful API 的优势 REST 约束 前文列表 用 Flask 来写个轻博客 (1) - 创建项 ...

  7. 用 Flask 来写个轻博客 (31) — 使用 Flask-Admin 实现 FileSystem 管理

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 编写 FileSystem Admin 页面 Flask-A ...

  8. 用 Flask 来写个轻博客 (30) — 使用 Flask-Admin 增强文章管理功能

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 实现文章管理功能 实现效果 前文列表 用 Flask 来写个 ...

  9. 用 Flask 来写个轻博客 (29) — 使用 Flask-Admin 实现后台管理 SQLAlchemy

    目录 目录 前文列表 扩展阅读 Flask-Admin BaseView 基础管理页面 ModelView 实现效果 前文列表 用 Flask 来写个轻博客 (1) - 创建项目 用 Flask 来写 ...

随机推荐

  1. UI自动化通过文字、父子元素,兄弟元素定位

    在百度首页,通过文字,父子元素,兄弟元素进行定位 一.文字定位: 通过界面上的文字进行定位,注意如果同一个页面上存在多个同样的文字的情况,返回的值会是多个,建议只存在一个情况下才用这方法. 如:定位百 ...

  2. HDU 1255 覆盖的面积 ( 扫描线 + 离散 求矩阵大于k次面积并 )

    覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  3. Educational Codeforces Round 69 (Rated for Div. 2) A~D Sloution

    A. DIY Wooden Ladder 题意:有一些不能切的木板,每个都有一个长度,要做一个梯子,求梯子的最大台阶数 做梯子的木板分为两种,两边的两条木板和中间的若干条台阶木板 台阶数为 $k$ 的 ...

  4. JQuery的链式编程与隐式迭代

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. Python之文件路径名的操作

    使用 os.path 模块中的函数来操作路径名 import os # 获取当前文件路径 path=os.path.abspath(__file__) # 获取绝对路径 /home/zzy/Pycha ...

  6. Tesseract-OCR识别中文与训练字库

    转自:https://www.cnblogs.com/lcawen/articles/7040005.html 关于中文的识别,效果比较好而且开源的应该就是Tesseract-OCR了,所以自己亲身试 ...

  7. Codeforces 633F 树的直径/树形DP

    题意:有两个小孩玩游戏,每个小孩可以选择一个起始点,并且下一个选择的点必须和自己选择的上一个点相邻,问两个选的点权和的最大值是多少? 思路:首先这个问题可以转化为求树上两不相交路径的点权和的最大值,对 ...

  8. HTML5:Canvas-绘制图形

    到本文的最后,你将学会如何绘制矩形,三角形,直线,圆弧和曲线,变得熟悉这些基本的形状.绘制物体到Canvas前,需掌握路径,我们看看到底怎么做. 栅格 在我们开始画图之前,我们需要了解一下画布栅格(c ...

  9. MongoDB 导入导出以及数据库备份

    -------------------MongoDB数据导入与导出------------------- 1.导出工具:mongoexport    1.1.概念:         mongoDB中的 ...

  10. fastjson 1.1.1填坑

    java封装Echart数据模型 xAxis  yAxis 属性  转json赋值失败..换名即可 解决办法:升级1.2.2后即可