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

项目前置配置

相关推荐
今晚务必早点睡2 小时前
微服务改数据库密码后服务仍能访问?一次“看似异常、实则常见”的生产现象全解析
数据库·微服务·oracle
老师我太想进步了20263 小时前
cmd连接MySQL及相关查询
数据库·mysql
難釋懷6 小时前
Redis命令-Set命令
数据库·redis·缓存
Linux-palpitate7 小时前
PostgreSQL(PG)的1主2从集群部署安装
数据库·postgresql
heartbeat..7 小时前
数据库基础知识体系:概念、约束、范式与国产产品
java·数据库·学习笔记·国产数据库
山峰哥8 小时前
数据库工程核心:SQL调优让查询效率飙升的实战密码
网络·汇编·数据库·sql·编辑器
Coder_Boy_8 小时前
基于SpringAI的在线考试系统-DDD业务领域模块设计思路
java·数据库·人工智能·spring boot·ddd
小雪_Snow9 小时前
Windows 安装 MySQL 8.0 教程【安装包方式】
数据库·mysql
无敌的牛9 小时前
MySQL初阶
数据库·mysql
不会C++的雾10 小时前
Linux操作系统(2)
linux·数据库·mysql