Flask中Model的设计
- 不能把Model的相关操作写在View里 , 全部写在Model里
- 通过编写CRUDMixin类 , 总领CRUD操作 ,
- 注意要把CRUDMixin类相应的方法改成类方法 , 实现代码的复用
- model的方法 , 尽量返回对象 , 不要返回数据
- model的to_dict方法 , 通过添加filter默认参数 , 让to_dict()方法使得更具拓展性
- session的add和commit通过严谨代码行实现 , 不用rollback , 尽早抛出错误
- 异常压缩问题 : 因为session没有rollback , 可能add了错误的数据 , 导致在下一次commit的时候才抛出异常
- 将自定义的方法修改为property , 避免了在template调用model的方法
Flask中DataBase的设计
- 避免使用外键
- postgresql 报错 column doesnot exist : postgrepsql不支持双引号 , 必须使用单引号
Flask中Template的设计
- 单独抽离出navi , 制作成一个macro
- 设置navi的参数为 items 和 search=False .使得template更加泛用
- 在template中复写父template的block , 提醒这个template中有这个block
- 封装
{% with errors = field.errors %}
, 对于使用了flash和validate的字段 , 就能高效简单的使用field
Flask中Form的设计
- 和Model一样 , 使用FormMixin , 在里面编写通用方法 , 比如通过编写dump2dict()方法 , 直接传给model的create方法就能避免使用popular_obj方法
- BaseForm设计的时候不要有primary key,以支持复用
Flask其他
- current_app只有在app启动的时候才存在 , celery项目不依赖flask,因此不能使用current_app
- 使用celery的项目 , 不能使用flask和内建的logging日志 , 要使用celery_task_logging , 否则无法写入(但是程序不报错)
- Flask处理请求 , 本质就是网络的多路复用 . 类似于新建一条线程 , 这条线程拥有整个上下文环境 , 所以我们在测试的时候需要手动建立上下文环境 . 这也说明了为什么asyncio会获取不到event_loop , 必须新建
Docker
- win和mac的docker其实是建立在虚拟Linux基础上 ,服务中使用的localhost指的是这个Linux环境的地址,而不是我们的宿主环境 , 因此volume和IP会受影响
- docker-compose的links的本质就是将redis的内部IP写入flask的hosts文件中
- docker-compose的command执行多条命令 , 可以设置前面命令后台最后一条前台
- 在bridge模式下 , Docker的容器都是通过veth-pair连接到docker的网关 , 并且docker网关使用NAT对网关进行IP翻译 , 最后NAT连接到Linux上的eth0网卡 , 进而连接到互联网
other
使用pycharm编码,很有可能导致os.getenv拿不到数据 , 此时重启pycharm即可
logging重复打印问题 :
通过print(app.logger.handlers),得知register_logging(app)这个初始化函数在执行app.logger.info()的时候依旧会被调用,会再次执行app.logger.addHandler(file_handler)。添加一个if len(app.logger.handlers) < 2,限制添加handler即可
还有就是 , 千万不要使记事本查看log文件 , 他就只是个视图 , 可能会延迟更新
gitlab迁移项目后 , 先删除本地仓库的全部远程连接 , 之后再添加新的远程连接 . 不能直接修改原先的origin.
requests.post中json参数和data参数的区别 :
不管
json
是str
还是dict
,如果不指定headers
中的content-type
,默认为application/json
data
为dict
时,如果不指定content-type
,默认为application/x-www-form-urlencoded
,相当于普通form表单提交的形式,此时数据可以从request.POST
里面获取,而request.body
的内容则为a=1&b=2
的这种形式,注意,即使指定content-type=application/json
,request.body的值也是类似于a=1&b=2
,所以并不能用json.loads(request.body.decode())
得到想要的值coverage测试pytest的覆盖率 :coverage run –source=celery_app -m pytest
其中 –source 选项和 -m 选项不能颠倒
模块设计 : 总共设计三层
- base层 : 此层必须高度抽象,规定必须要实现的方法
- 中间层: 实现base层的所有方法
- 实现层 : 部分实现中间层的方法
连接远程redis : 必须要把conf里的
bind
取消注释 , 改为bind 0.0.0.0