fastapi后端, elementui前端, jinja2和vue做数据驱动模块踩坑记录
Fastapi开发记录
工具介绍
前端技术栈: Vue, ElementUI
后端技术栈: fastapi, pymongo, jinja
工具集: vscode, docker, python, git, mongo
编程部分的坑
学习一个简单的todo功能的前后端实现. fastapi后端, elementui前端, jinja2和vue做数据驱动模块踩坑记录
防火墙问题
众所周知的原因, 国内防火墙让docker源已经python源的访问及其的缓慢; 因为实际的需求, 我的项目是完全基于docker的. 所以必须要配置一下docker的环境.
Docker 环境
win: docker desktop --> settings --> docker engine 配置如下👇:
{
"something-else": "",
"registry-mirrors": [
"http://hub-mirror.c.163.com"
]
}
Python 环境
Python的依赖都在Dockerfile里面安装, 需要 -i 命令指定仓库, 配置如下👇
FROM python:3.8.13-buster
ADD . /code
WORKDIR /code/src
RUN pip install -r ../requirements.txt -i https://pypi.douban.com/simple
RUN pip install -U fastapi -i https://pypi.douban.com/simple
依赖匹配问题
由于jinja2>=3.1.0以上的版本丢弃了一些用法如下. 具体用法详见jinja_release
contextfilter and contextfunction are replaced by pass_context.
evalcontextfilter and evalcontextfunction are replaced by pass_eval_context.
environmentfilter and environmentfunction are replaced by pass_environment.
所以可能会有人在使用的过程中出现这样的问题module 'jinja2' has no attribute "'contextfunction'". 这种时候完全不用慌, 只需要安装最新版的fastapi即可, 官方已经解决了这个问题了.
时区问题
由于ElementUI比较智能, 生成的timezone会根据当地的时区进行放缩, 比如中国UTC+8:00时间. 在计算时间时会按照自动缩小8*3600*1000 ms. 在显示的时候又会自动加上. 但是神奇的事情是这个时区标志不知道存储在哪个变量里面, 后端传输的timezone就不会自动加上8*3600*1000 ms.所以从ElementUI的时间日期组件生成的时间如08:00:00存到数据库在读取后就会变成00:00:00. 所以需要如下操作👇
real_time = new Date(element_generated_time.getTime() + 8 * 3600 * 1000)
自己动手, 丰衣足食了属于是. 像Python datetime就不那么智能, 不管三七二十一就根据当前时间直接计算timestamp就不会出现-8:00的情况.
前后端数据交互的问题
关于Jinja如何与Vue共存, 这个问题在李辉老师的博文里讲的很清楚, 我采用他提议的最简单的方法, 下面此方法节录下来👇
- 使用 Jinja2 的 raw 标签标记 JavaScript 模板代码
第一种方式最直观,使用 Jinja2 的 raw 标签声明原生代码块,也就是不需要进行后端渲染的代码块。使用 raw 和 endraw 标签把 JavaScript 模板部分标记出来即可,比如:
{% raw %}
<div id="app">
{{ js_var }}
</div>
{% endraw %}
这种方式的副作用最少,尽管需要多几行代码,但不会影响你写 Jinja2 或其他 JavaScript 库的语法习惯。
根据我个人的习惯, 完全基于Vue进行数据驱动开发的体验会比同时使用Jinja与Vue两种数据传输方式要更方便. 当然如果要在前端使用Vue进行数据的获取, 统一的IP是必不可少的, 那么在前后端我分别采用下述方法实现本地ip的获取👇
<script>
Vue.use(VueResource)
var base_url = "http://" + window.location.host;
</script>
def get_host_ip():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 80))
ip = s.getsockname()[0]
finally:
s.close()
return ip
后记
经过如上的一些配置, 匹配对相关组件文档和源码的阅读, 就可以较顺利的完成简单CRUD网页的开发.
当然docker的部署和docker-compose文件的编写等也需要一些时间进行熟悉. 如果想要遵循代码开发规范的话, 那么git和.gitlab-cl.yml等工具也是不可或缺的.

浙公网安备 33010602011771号