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共存, 这个问题在李辉老师的博文里讲的很清楚, 我采用他提议的最简单的方法, 下面此方法节录下来👇

  1. 使用 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等工具也是不可或缺的.

posted @ 2022-05-26 23:23  Aibot  阅读(1246)  评论(0)    收藏  举报