news 2026/7/24 23:30:29

FastAPI分层架构实战:高效API开发指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FastAPI分层架构实战:高效API开发指南

1.路径讲解

boss-api/ ├── main.py # FastAPI应用主入口 │ ├── requirements.txt # Python依赖包 │ └── app/ # 应用核心代码 ├── __init__.py │ │ ├── models/ # 数据模型层 (Tortoise ORM) │ ├── __init__.py │ ├── user.py # 用户相关模型 │ ├── apis/ # API路由层[接受参数,返回数据] │ ├── __init__.py │ └── user_api.py # 用户相关API │ └── schemas/ # 数据验证层 (Pydantic) │ ├── __init__.py │ └── user.py # 用户请求/响应模型 │ │ ├── services/ # 业务服务层 (逻辑) │ ├── __init__.py │ ├── user.py # 用户相关的业务代码/方法 │ │ ├── core/ # 核心文件 │ ├── __init__.py │ ├── database.py # 数据库连接信息 ├── config/ # 配置文件 │ ├── __init__.py │ ├── settings.py # 多环境配置

2.区别

我们将昨天的写法改变了一下

1.昨天是

模型写在models文件下 路由和方法都写再routers中 而请求体写在schemas中

在main主路由下调用 day02下routers中的方法来完成的

2.今天我们将路由和方法分开写入

apis只写我们的路由方法 如下

@day03_user_api.post("/") async def login(username: str, password: str): code, message = await user.login(username, password) return {"code": code, "message": message}

我们走的是post添加的接口 在下面走我们 services中的user.py 也就是我们的方法

from day02.models.book import User async def login(username: str, password: str): user = await User.filter(username=username).first() if not user: return 404, "用户不存在" if user.password_hash == password: return 400, "登录成功" return 404,"密码错误"

从我们路由apis user 中传到 services 然后使用我们的方法 进行正常的流程

我们return返回要于我们路由中相等 code,msg,data

return 404,"密码错误",None

路由中用 code,msg,data 接受然后再用字典的方法输出

code, message = await user.login(username, password)
return {"code": code, "message": message}

我们将所有的全部分开单独写一个文件 这样方便我们查找 不会混乱

3.查询

1. 从A表查询B表 B表有A表的外键

  • 科室列表:展示所有科室,显示科室名称、楼栋、楼层、医生数量

从我们的科室列表 每个科室下都有哪些医生:

async def get_departments(): # related_name 是 doctors,预加载关联医生列表 departments = await Department.all().prefetch_related("doctors") departments_list = [] for department in departments: # 遍历当前科室下所有医生 doctor_list = [ { "id": doctor.id, "name": doctor.name, "title": doctor.title, "specialty": doctor.specialty, "phone": doctor.phone, "daily_quota": doctor.daily_quota, "status": doctor.status, "created_at": doctor.created_at, "updated_at": doctor.updated_at } for doctor in department.doctors ] departments_list.append({ "id": department.id, "name": department.name, "building": department.building, "floor": department.floor, "description": department.description, "Doctor": doctor_list # 一个科室对应多个医生,数组 }) return 200, "获取成功", departments_list

我们先查询所有的科室关联我们的doctors表

departments = await Department.all().prefetch_related("doctors")

定义一个我们要返回的列表 departments_list = []

循环遍历我们的departments 每条数据赋值给department

在根据我们的科室id去查找我们的医生表 历当前科室下所有医生

在下面输出我们的科室信息 append加入我们的医生表 一个科室对应多个医生,数组

最后返回给路由

科室id=1 下有医生id=1,2等

2.从一个表查我们的外键表

  • 管理联系方式:在患者列表中点击"联系方式",可查看/创建/编辑该患者的一对一联系方式(手机号、微信、邮箱、紧急联系人、住址)
async def get_patient(id): patient = await Patient.get_or_none(id=id).prefetch_related("contact") if not patient: return 404, "患者不存在", None # 安全处理:防止没有contact时报错 contact_info = None if hasattr(patient, "contact") and patient.contact: contact_info = { "phone": patient.contact.phone, "wechat": patient.contact.wechat, "email": patient.contact.email, "contact_name": patient.contact.contact_name, "contact_phone": patient.contact.contact_phone, "address": patient.contact.address, } patient_data = { "id": patient.id, "name": patient.name, "gender": patient.gender, "age": patient.age, "id_card": patient.id_card, "created_at": patient.created_at, "updated_at": patient.updated_at, "contact": contact_info } return 200, "获取成功", patient_data

从患者表 查询患者的信息资料

patient = await Patient.get_or_none(id=id).prefetch_related("contact") if not patient: return 404,“患者不存在",None

先查询id时候存在 预加载 contact

然后定义一个用来返回的空列表 上面是我们当前患者 下面是我们的患者信息资料

先查找我们id对应的患者资料

if hasattr(patient, "contact") and patient.contact: contact_info = { "phone": patient.contact.phone, "wechat": patient.contact.wechat, "email": patient.contact.email, "contact_name": patient.contact.contact_name, "contact_phone": patient.contact.contact_phone, "address": patient.contact.address, }

是我们的详细资料然后加到我们的患者表中

patient_data = { "id": patient.id, "name": patient.name, "gender": patient.gender, "age": patient.age, "id_card": patient.id_card, "created_at": patient.created_at, "updated_at": patient.updated_at, "contact": contact_info }

"contact": contact_info 是我们的详细治疗 我们上面已经定义出来 直接加到我们的患者表就可以了

上面是信息 下面是治疗 这是1对1 查询

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/24 23:28:26

灵境1911 短剧工业化系统:AI短剧量产工作流全解析

AI短剧正从"单条手工制作"向"工业化批量生产"演进。据《中国网络视听发展研究报告(2026)》数据显示,2026年Q1全行业上线微短剧约12.8万部,其中AI短剧约12.2万部,占比超过95%。AI短剧占整个AI行业算…

作者头像 李华
网站建设 2026/7/24 23:28:09

HarmonyOS开发实战:小分享-深浅色主题切换——基于 resources/dark 适配

前言 深浅色主题 是现代移动应用的标配功能,让应用在浅色和深色模式下都有良好的视觉体验。HarmonyOS 通过 resources/dark/ 目录实现主题化资源适配。小分享 App 的 EntryAbility 中设置了 COLOR_MODE_NOT_SET 跟随系统。本篇讲解完整的深浅色适配方案。详细 API …

作者头像 李华
网站建设 2026/7/24 23:27:32

Switch游戏安装终极指南:3分钟学会所有格式兼容方法

Switch游戏安装终极指南:3分钟学会所有格式兼容方法 【免费下载链接】Awoo-Installer A No-Bullshit NSP, NSZ, XCI, and XCZ Installer for Nintendo Switch 项目地址: https://gitcode.com/gh_mirrors/aw/Awoo-Installer 还在为Switch游戏安装的各种格式头…

作者头像 李华
网站建设 2026/7/24 23:27:31

3步解锁网易云音乐限制:ncmdump让NCM格式音乐重获播放自由

3步解锁网易云音乐限制:ncmdump让NCM格式音乐重获播放自由 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾经在网易云音乐下载了喜爱的歌曲,却发现只能在特定客户端播放?ncmdump正是为你解…

作者头像 李华
网站建设 2026/7/24 23:25:07

AI 芯片简报 07.21-07.24:NVIDIA Vera 亮剑、AMD 2nm GPU、Google 叛逃 CoWoS

每期覆盖 3-4 天的 AI 芯片动态。个人视角,不追求面面俱到——只讲我认为重要的。周二、五更新。7 月 21 日到 24 日这四天,AI 芯片行业发生的事,放在任何一个正常的年份,都够写一个季度的头条。NVIDIA、AMD、Intel 三巨头在 72 小…

作者头像 李华
网站建设 2026/7/24 23:24:37

如何快速掌握CTF流量分析:5分钟上手CTF-NetA终极指南

如何快速掌握CTF流量分析:5分钟上手CTF-NetA终极指南 【免费下载链接】CTF-NetA CTF-NetA是一款专门针对CTF比赛的网络流量分析工具,可以对常见的网络流量进行分析,快速自动获取flag。 项目地址: https://gitcode.com/gh_mirrors/ct/CTF-Ne…

作者头像 李华