《知讯头条》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浏览历史模块

项目前置配置

相关推荐
红队it2 小时前
【数据分析】基于Spark链家网租房数据分析可视化大屏(完整系统源码+数据库+开发笔记+详细部署教程+虚拟机分布式启动教程)✅
java·数据库·hadoop·分布式·python·数据分析·spark
网硕互联的小客服2 小时前
哪些外在因素条件会导致服务器的延迟过高?
linux·运维·服务器·数据库·安全
就叫飞六吧2 小时前
三步搭建“钉钉待办推送” (curl版)+工作通知
数据库·redis·钉钉
打不了嗝 ᥬ᭄2 小时前
【MySQL】表的约束与基本查询
数据库·mysql
无心水2 小时前
【神经风格迁移:性能】24、神经风格迁移全链路监控实战:基于Prometheus+Grafana的性能调优指南
数据库·人工智能·深度学习·机器学习·grafana·prometheus·神经风格迁移:性能
augisTrench2 小时前
LatentFlowx是一种非令牌的、状态驱动的推理运行时,旨在通过以下方式降低计算成本并提高可控性
数据库
橘子真甜~2 小时前
Reids命令原理与应用2 - Redis网络层与优化,pipeline,发布订阅与事务
数据库·redis·缓存·事务·发布订阅·lua脚本·acid特性
源代码•宸2 小时前
goframe框架签到系统项目开发(用户认证中间件、实现Refresh-token接口)
数据库·经验分享·后端·算法·中间件·跨域·refreshtoken
建群新人小猿2 小时前
陀螺匠 企业助手-经我审批
服务器·数据库·php