《知讯头条》Python后端项目详解---基于FastAPI和SQLAlchemy

一、项目介绍

1.1、项目背景

随着互联网普及,用户对新闻咨询获取有了更高的要求:快速、个性化、可追溯。传统新闻应用在响应速度、内容推荐和用户体验上存在一定的局限性。

1.2、项目目标

为了满足用户对新闻浏览、收藏、历史记录等核心场景需求。我们特地研发了这个项目。

1.3、项目架构

我们的项目基于FastAPI和SQLAlchemy构建,采用Starlette异步架构设计

1.4、项目功能

实现了用户注册、登录、新闻浏览、收藏和历史记录等全流程功能

分为了用户管理、新闻内容、点赞收藏、浏览历史四大核心模块

1.5、设计过程中遇到的问题

1.6、开发完怎么进行测试的(有没有分场景,写用例)

1.7、项目亮点,用到的核心技术

二、业务详细流程

2.1用户管理模块

用户注册

业务流程:

用户进入登录注册页面,如果用户有账号,直接登录,没有账号,进入注册流程:

用户输入用户名和密码,后端会先通过Pydantic验证数据模型,不通过报错,通过后,再查询用户名是否存在,如果存在,提示用户名已经存在,如果不存在

①将创建用户,创建用户这里我们是封装了一个方法到curd包下面。传递用户数据,包含用户名和密码,这样方法首先拿到密码进行argon2哈希加密算法加密。接着创建一个SQLAlchemy ORM 用户对象。把它添加到数据库中,提交并,刷新,拿到包含 User 模型定义的所有字段并返回

②创建访问令牌token,也是封装了一个方法放在了curd包下面,传入用户 id 来为该用户创建访问令牌。该方法首先生成一个 UUID 格式的随机访问令牌,并设置令牌 7 天的有效期,接着根据用户id查询该用户是否已有令牌记录,如果已有令牌记录,就更新令牌内容和过期时间;如果没有令牌记录,就创建一个新的 UserToken ORM 对象,包含用户 id、新生成的令牌和过期时间,将其添加到数据库并提交,最后返回生成的访问令牌(返回的 token 无 Bearer 前缀)。

将生成的访问令牌和用户信息封装到字典类型的 response_data 中,通过 success_response 返回给前端,同时提示 "登录成功"。

用户登录

业务流程:

如果用户有账号,进入登录流程:

用户输入用户名和密码,后端会先通过Pydantic验证数据模型,不通过报错,通过后,首先

①调用校验方法验证用户信息,传入用户名和密码,该方法先根据用户名查询数据库获取用户对象,如果查询不到用户,直接返回用户名或密码错误;如果查询到用户,

再调用验证密码的方法,传入用户输入的密码和在数据库查到的密码。进行校验。如果:若用户信息验证失败,直接抛出异常提示 "用户名或密码错误";若验证成功,则

②调用创建访问令牌的方法(封装在 curd 包下)得到令牌,该方法通过传入用户 id 来为该用户创建访问令牌。该方法首先生成一个 UUID 格式的随机访问令牌,并设置令牌 7 天的有效期,接着根据用户id查询该用户是否已有令牌记录,如果已有令牌记录,就更新令牌内容和过期时间;如果没有令牌记录,就创建一个新的 UserToken ORM 对象,包含用户 id、新生成的令牌和过期时间,将其添加到数据库并提交,最后返回生成的访问令牌(返回的 token 无 Bearer 前缀)。

将生成的访问令牌和用户信息封装到字典类型的 response_data 中,通过 success_response 返回给前端,同时提示 "登录成功"。

获取用户信息

用户在已登录状态下触发获取用户信息操作(如进入个人中心),后端开始处理获取用户信息的请求:

前端在请求头的 authorization 字段中携带包含 Bearer 前缀的令牌信息,后端

①首先从该字段中提取出纯令牌字符串(去除 Bearer 前缀)。接着

②调用通过令牌查询用户信息的方法(封装在 curd 包下),该方法首先根据令牌字符串查询数据库中的 UserToken 表,获取对应的令牌记录:

  • 如果未查询到令牌记录,或查询到的令牌记录其过期时间早于当前时间(令牌已过期),则返回空值;
  • 如果查询到有效的令牌记录(存在且未过期),则提取该记录中的 user_id,再通过 user_id 查询数据库中的 User 表,获取完整的用户对象并返回。

③若通过令牌未查询到有效的用户信息(返回空值),后端直接抛出异常提示 "用户没有登录";若查询到有效的用户对象,先将用户对象转换为可序列化的 JSON 格式数据,再将该用户信息封装到字典类型的 data 中,通过 success_response 返回给前端,同时提示 "获取用户信息成功"。

更新用户信息

用户在已登录状态下触发更新用户信息操作(如修改个人资料),后端会先通过Pydantic验证数据模型,不通过报错,通过后,后端开始处理更新用户信息的请求:

前端在请求头的 authorization 字段中携带包含 Bearer 前缀的令牌信息,同时传递需要更新的用户信息数据(如昵称、手机号等),后端首先

①调用通过令牌查询用户信息的方法,校验用户是否处于登录状态:

若未查询到有效的用户信息(令牌不存在、过期或关联不到用户),直接抛出异常提示 "用户没有登录";

若校验通过,获取到当前登录的用户对象,

②调用更新用户信息的方法(封装在 curd 包下),传入待更新的用户信息、数据库会话和当前用户对象。

该更新方法首先将前端传递的更新数据转换为字典格式,并过滤掉未设置、值为 None 的属性(仅保留需要实际更新的字段);接着通过属性赋值的方式,逐个将新值更新到当前用户对象对应的字段上;更新完成后提交数据库事务,再刷新用户对象(重新从数据库获取最新的用户数据),确保返回的用户信息是最新状态。

最终将更新后的用户对象封装到字典类型的 data 中,通过 success_response 返回给前端,同时提示 "更新用户信息成功"。

修改用户密码

修改用户密码流程描述

用户在已登录状态下触发修改密码操作,后端会先通过Pydantic验证数据模型,不通过报错,通过后,后端开始处理修改用户密码的请求:

前端在请求头的 authorization 字段中携带包含 Bearer 前缀的令牌信息,同时传递旧密码和新密码数据,后端首先执行以下校验步骤:

①调用通过令牌查询用户信息的方法,校验用户是否处于登录状态:若未查询到有效的用户信息(令牌不存在、过期或关联不到用户),直接抛出异常提示 "用户没有登录";若校验通过,获取到当前登录的用户对象。

②调用用户信息校验方法,传入当前用户的用户名和前端提交的旧密码:先根据用户名查询用户对象(确保用户存在),再使用 argon2 哈希加密算法对应的校验方法,对比旧密码明文与数据库中存储的哈希密码是否一致,若不一致则抛出异常提示 "旧密码错误";若校验通过,返回当前用户对象。

校验全部通过后,

③调用修改用户密码的方法(封装在 curd 包下),传入新密码、数据库会话和当前用户对象:该方法首先使用 argon2 哈希加密算法对新密码进行哈希处理,再通过 SQLAlchemy 的 Update 语句,根据用户 id 更新数据库中该用户的密码字段为加密后的新密码;更新完成后提交数据库事务,再刷新用户对象(重新从数据库获取最新的用户数据),确保返回的用户信息是最新状态。

最终将更新后的用户对象封装到字典类型的 data 中,通过 success_response 返回给前端,同时提示 "修改用户密码成功"。

2.2新闻管理模块

2.3点赞收藏模块

2.4浏览历史模块

项目前置配置

相关推荐
剩下了什么4 小时前
MySQL JSON_SET() 函数
数据库·mysql·json
山峰哥5 小时前
数据库工程与SQL调优——从索引策略到查询优化的深度实践
数据库·sql·性能优化·编辑器
较劲男子汉5 小时前
CANN Runtime零拷贝传输技术源码实战 彻底打通Host与Device的数据传输壁垒
运维·服务器·数据库·cann
java搬砖工-苤-初心不变5 小时前
MySQL 主从复制配置完全指南:从原理到实践
数据库·mysql
山岚的运维笔记7 小时前
SQL Server笔记 -- 第18章:Views
数据库·笔记·sql·microsoft·sqlserver
roman_日积跬步-终至千里8 小时前
【LangGraph4j】LangGraph4j 核心概念与图编排原理
java·服务器·数据库
汇智信科8 小时前
打破信息孤岛,重构企业效率:汇智信科企业信息系统一体化运营平台
数据库·重构
野犬寒鸦8 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
晚霞的不甘9 小时前
揭秘 CANN 内存管理:如何让大模型在小设备上“轻装上阵”?
前端·数据库·经验分享·flutter·3d
市场部需要一个软件开发岗位10 小时前
JAVA开发常见安全问题:纵向越权
java·数据库·安全