Flask-RESTful 后端开发踩的若干的坑

发布于 2018-11-20  4,580 次阅读


刚刚 18 点生死极速的把几个文档和项目视频踩着时间线提交了上去,至此我的第一次正规的项目比赛的初赛就结束了。
Intel杯本次比赛的主题是 Web + AI,方向稍微有一点偏的,不过还好是工作室正好不久前有考虑过一个项目的 ideal 可以拿过来用,然后几经波折最终由我来用 Flask 开发 RESTful APi 的后端。
开发过程中踩了各式各样的坑,说实话很多都可能已经忘记了,就趁着还没有忘光把该记下来的东西记一点。

字典查询问题

先从一个简单的 python 问题开始。
遇到这样一个问题,需要前 post 一些数据更新后端数据库,然而有些字段是可填可不填的,在开发的时候我一开始是这么写的:

if a['test']:
    do something

然而服务器会返回 500 错误。后来和学长一点一点 debug 才在函数找到这个问题,是因为访问了不存在的值于是直接返回了错误,这样写就可以了:

if 'test' in a:
    do something

这其实是一个很弱智的问题,不过在写的时候之前没遇到过,python 基础功不扎实就犯了这个错。(是啊明明我是一个前端来着)

引用循环问题

当在开发一个中小型应用的时候经常会需要些很多很多函数和类来互相调用,Flask 在开发过程中一般会在 __init__.py 中初始化应用,而初始化很多时候需要创建数据库,创建的数据库一般在 models 的类中也会被调用而进行操作,Flask 绑定蓝图和路由是需要 import resources 的,而 resources 一般需要 import models, 这就形成了一个循环引用,一不小心就会出现can not import XXX的尴尬情况。
其实解决方法就是把特定 import 错开而不放在文件顶部,延迟引用。例如上面的例子中,绑定蓝图可以放在 __init__.py 的底部,那么引用 resources 可以放在绑定蓝图函数上部,其他函数下方,这样就不会存在这个问题了。

跨域问题

当编写 RESTful API 时一个经典问题就是跨域问题,因为 flask 后端和前端一般不会跑在一个服务器中,跨域是必须要解决的问题,这个时候可以选择使用 Flask-cros 这个库,大概只需要两行放在 __init__.py 文件中即可正常使用。

前端跨域

在前后端都确认跨域的函数/库写好后仍然不能跨域,可以先不要急着怀疑 Flask-cros 或其他库的问题。在这次开发中遇到了这样的问题,最后解决很有可能是前端绑定的路由出现问题,在这种情况下似乎报错和跨域的报错非常类似。

Flask-login 使用

项目中引入了 Flask-login 来简化登录,但是一开始 @login_require 无法成功还是报错,阅读文档发现文档第一二行代码似乎是必要的,但是文档没有明确说放在哪边(虽然现在看来显然是应该放在初始化过程中),最后通过阅读他人的代码发现需要在 __init__.py 中引用相应的库并写入:

login_manager = LoginManager()
login_manager = LoginManager()

即可正常使用

Flask-login 使用小技巧

使用 current_user 可以便捷的访问到用户登录的账户,current_user 本身即是 User 类的实例(如果 user 的类是 User),例如:

current_user.id

user = User()
user = User.query.filter_by(global_id=args['global_id']).first().id

两者是一样的。

最优实践

在很长一段时间内我都迷茫于 Flask 项目结构、路由的绑定方法这样一些结构性的问题,我在网上看了十几个 Flask 应用,并根据他们的代码一点点去修正我的代码,重构项目结构,而这样一点一点踩坑到最后回头一看发现代码和 Flask 官方文档已经没有什么大的差别了。一开始不用 Flask 官方的结构是觉得太过简单不太好用,但最后才发现这已经是最稳定和最便利的方法了,Flask-login也同样如此。所以一定要好好研读官方文档。


Fly me to the moon