去年下半年,我接了个活儿:给一个做二手教材生意的朋友搭一套网上书店系统。需求并不复杂——能展示图书、能搜索、能加购物车、能下单,最好还能有个简单的后台管理库存。我当时的想法很直接,后端用Python把最核心的业务逻辑跑通,前端用Vue3做单页应用,整套系统自己一个人从零开始写。今天这篇博文就把这个项目的完整开发经历摊开来讲,包括技术选型、数据模型、接口设计、前端页面、联调过程中的坑,以及最终上线的部署方式。如果你也想做一套类似的书店、商城或后台管理系统,这篇文章应该能帮你少走不少弯路。
先说一句:这个项目我内部习惯叫它“python159网上书店系统”,这个编号不是版本号,而是我自己给它起的项目代号。159对我来说意味着“一套流程、五个核心模块、九次重构”,后面会提到这些数字分别对应什么。整个系统的技术栈选型是:Python 3.10 + FastAPI + SQLite/MySQL + Vue3 + Vite + Pinia + Element Plus。文章里所有代码都是实际跑过的,有些细节我会特意标注为什么当时那么写、以及更好的做法是什么。
1. 系统设计与选型:为什么最终定了Python+Vue3这套组合
1.1 业务需求拆解:一个书店系统的最小功能闭环
很多人在动手写项目之前容易犯一个通病:上来就画原型、建表,结果需求根本不清晰。我拿到这个项目的第一件事,是把用户从进店到买书的全流程走了一遍,然后拆成下面这些最小功能点:
- 图书展示:用户进入首页能看到图书列表,每本书包含封面、书名、作者、定价、简介、库存状态。
- 图书搜索:支持按书名关键字模糊搜索,搜索后支持分页浏览。
- 图书详情:点击某本书进入详情页,能看到完整信息,并可以选择“加入购物车”。
- 购物车:支持添加商品、修改数量、删除商品、清空购物车。
- 下单结算:从购物车生成订单,订单包含商品明细、总价、下单时间、订单状态。
- 后台管理:管理员可以新增图书、修改库存、下架图书、查看订单列表。
- 用户登录注册:手机号/用户名注册、登录,登录后购物车和订单关联到用户。
这套闭环看起来常规,但其实从开发量来说并不小。如果全部自己撸,前端至少要7个以上页面,后端至少十几个接口,再加上管理员鉴权、用户鉴权,很容易写着写着就失控。项目的成败往往不取决于某个页面做得多么炫酷,而是你有没有提前把数据模型定清楚。
1.2 Python后端的选型逻辑:FastAPI、Django还是Flask
可能有人会问,Python做后端框架那么多,Django自带Admin后台,Flask轻量灵活,为什么最后选了FastAPI。
答案是三个字:异步和自动文档。网上书店系统的查询接口居多,图书列表、搜索、详情,这些都是典型的IO密集型场景。FastAPI原生支持async语法,配合异步数据库驱动在高并发情况下有更好的吞吐表现。更重要的是,FastAPI基于Pydantic做请求参数校验,写完接口之后会自动生成Swagger文档,前端联调的时候直接打开/docs界面就能看每一个接口的参数和返回结构,省去大量沟通成本。
当然,FastAPI也不是没有缺点。它的生态比Django薄一些,尤其是Admin后台需要自己写。但恰巧我这次不打算用框架自带的Admin,而是直接用Vue3做一个独立的后台管理页面,这样前端同学对管理的界面风格更可控,将来要加表单校验、导出报表之类的功能也方便。至于Flask,它确实轻,但实际上到了项目后期,你会发现该做的集成一个都省不掉——数据库迁移、参数校验、跨域处理全都要自己组装,时间成本反而更高。所以综合权衡下来,FastAPI是最合适的。
1.3 前端Vue3的具体版本路线:Vite + 组合式API + Pinia
前端选择Vue3而不是Vue2或React,主观因素占了很大一部分,但也有客观理由。Vue3的Composition API把按功能组织代码的能力提升了一个台阶,一个购物车模块相关的逻辑可以集中放置,而不是在Vue2里靠mixin东拼西凑。配合