萌新入门:FastAPI+Python 前后端交互全解析(如何通过Fastapi实现用户登录,注册,查看用户信息项目)

一.简介

        (1)FastAPI 是一款现代、轻量、高性能的 Python Web 框架,专门用来快速构建 API(应用程序编程接口,也就是前后端 / 服务间传递数据的 “通道”)。它是近几年 Python 生态中最火的 Web 框架之一,尤其适合萌新快速上手写后端接口        (2)FastAPI 适合做什么:

  • 前后端分离项目的后端 API(比如我们之前写的注册 / 登录接口);
  • 微服务(拆分后的小服务间的接口);
  • 数据接口(比如给前端提供数据库里的商品信息);
  • 快速原型开发(想快速验证一个想法,几小时就能搭好后端)

二.FastAPI+Python 前后端交互全解析

        作为编程萌新,刚接触前后端交互时总被一堆概念绕晕:FastAPI 怎么写接口?requests 库为啥返回<Response [200]>?后端的Request对象到底是啥?今天就结合实战代码,把这些知识点掰开揉碎,让你彻底搞懂前后端交互的底层逻辑!

1.先搞懂:前后端交互的本质是什么?

用一个餐厅点餐的比喻就能秒懂:

  • 前端:你(顾客),负责 “提需求”(比如要一碗牛肉面);
  • 后端:厨房(服务器),负责 “处理需求”(煮面、加牛肉);
  • HTTP 协议:服务员,负责传递你的需求和厨房的结果;
  • 请求:你喊 “服务员,来碗牛肉面”;
  • 响应:服务员端来做好的牛肉面(或告诉你 “卖完了”)。

我们写的 Python 前端脚本就是 “顾客”,FastAPI 后端就是 “厨房”,两者靠 HTTP 协议传递数据 —— 这就是前后端交互的核心!

2.项目需求

使用fastAPI实现登录、注册接口
1.提供用户注册接口,当用户名和密码不为空 且 用户名长度大于6,密码长度大于8且包含下划线、字母和数字时,将用户数据保存下来。(注意:不能有相同的用户名)

2.提供用户登录接口,当用户名和密码正确时,提示:欢迎xxx,否则提示:用户名或密码不正确!

3.前后端代码整体思路分析:从功能设计到交互逻辑(完整代码放在文章最后)

        作为刚接触Fastapi的初学者,我们使用“FastAPI 后端接口服务 + Python 命令行前端客户端”组合来满足项目需求,以下从后端设计思路前端设计思路前后端交互逻辑三个维度拆解整体思路(以项目注册功能为例)

1.前端代码设计思路

import requests
requests是 Python 生态中最常用的HTTP 请求库,相当于前端的 “传话员”—— 它帮我们把用户的操作(比如注册、登录)转换成后端能识别的 HTTP 请求,再把后端的响应结果带回来。没有这个库,Python 代码就没法和后端服务器 “对话”。

while True: user_input = input('1、注册\n2、登录\n3、查看\n4、退出\n请输入你要进行的操作:')
  • while True:创建一个无限循环,让程序一直运行,直到用户选择 “退出”(避免用户每操作一次就重新运行一次代码);
  • input(...):在命令行打印操作菜单,等待用户输入指令(1/2/3/4),并把用户输入的内容存到user_input变量里。

这一步是前端和用户交互的 “入口”,相当于餐厅的 “点餐台”,用户告诉点餐员要什么,点餐员再传给厨房。

#前端注册功能 if user_input == '1': user = input("用户名:") password = input("密码:") res = requests.post("http://127.0.0.1:8000/user/register",params={"username":user,"password":password}) result = res.json() print(f"{result["result"]}")
  • user = input("用户名:")/password = input("密码:"):提示用户输入用户名和密码,并存到变量里(收集用户的 “点餐需求”);
  • res = requests.post("http://127.0.0.1:8000/user/register",params={"username":user,"password":password})
    • requests.post:发送POST 请求到后端注册接口("http://127.0.0.1:8000/user/register");
    • params={"username":user,"password":password}:把用户名和密码作为URL 查询参数拼到请求地址后面(比如http://127.0.0.1:8000/user/register?username=test&password=test_123456),传给后端;
    • res:接收后端返回的响应对象(相当于后端 “做好的菜 + 小票”);
  • result = res.json():把后端返回的 JSON 格式字符串转换成 Python 字典(解析 “小票” 上的内容);
  • print(f"{result["result"]}"):提取字典里的result字段(后端返回的注册结果),打印给用户看(展示 “菜品” 和 “评价”)

易混淆点:在requests.post("http://127.0.0.1:8000/user/register", params={"username":user,"password":password})

paramsrequests库的一个参数,它的核心作用是:将字典形式的键值对,转换成 URL 的 “查询参数”(Query Parameters),拼接到请求 URL 的末尾。

举个具体例子:如果用户输入的用户名是testuser,密码是test_123456,那么params={"username":"testuser","password":"test_123456"}会被转换成:?username=testuser&password=test_123456

最终发送请求的完整 URL 就变成了:http://127.0.0.1:8000/user/register?username=testuser&password=test_123456,将这个经过处理的URL传给后端我们写的注册接口@app.post('/user/register')

 elif user_input == '2': user = input("用户名:") password = input("密码:") res = requests.post(urls[1], params={"username": user, "password": password}) result = res.json() print(f"{result["result"]}") elif user_input == '3': res = requests.post(urls[2]) result = res.json() print(f"{result}") elif user_input == '4': break else: print("输入的操作错误请重新输入")
以上分别是项目登录、查看、退出功能,里面具体方法与注册功能一致

requests.post返回的是一个Response对象(包含响应状态码、头信息、内容等),直接打印这个对象会显示<Response [状态码]>(200 表示请求成功)。如果你想获取后端返回的数据,需要用res.json()(如果后端返回 JSON)或res.text(如果返回纯文本)解析响应内容。

2.后端代码(FastAPI)设计思路

后端的核心定位是 “提供数据处理接口,维护用户数据,校验业务规则”,整体思路围绕 “接口功能 + 数据管理 + 规则校验” 展开,让我们先来一段一段解析基础的 FastAPI 后端代码:

import uvicorn from fastapi import FastAPI, Request 
  • import uvicorn:导入Uvicorn 服务器——FastAPI 是基于 ASGI 协议的框架,需要 ASGI 服务器来 “监听网络请求”(就像餐厅需要服务员站在门口接客),Uvicorn 就是负责这件事的工具。
  • from fastapi import FastAPI, Request
    • FastAPI:导入 FastAPI 框架的核心类,用来创建后端服务的 “主实例”(相当于搭建餐厅的整体框架);
    • Request:导入 FastAPI 封装的 “请求对象”,用来获取前端发送的请求数据(比如用户名、密码)。

app = FastAPI()

        这行代码创建了一个 FastAPI 应用实例,命名为app—— 它是后端服务的 “核心入口”,所有接口、功能都要挂载到这个实例上。可以把它想象成:你开了一家叫app的餐厅,接下来要在餐厅里设置 “注册窗口”“登录窗口” 等业务区域。

user_datas = [{"username": "admin123","password": "admin_123",}]

    (1)用 Python 列表user_datas模拟 “数据库”(实际项目会用 MySQL/SQLite 等真实数据库,这里为了简化用列表);

    (2)列表里预存了一个初始用户{"username": "admin123","password": "admin_123"},用来测试 “用户名重复” 的逻辑;

    (3)作用:存储已注册用户的账号密码,后续注册时需要检查用户名是否已存在。

def judgment(username, password): # 条件1:用户名长度大于6 username_valid = len(username) > 6 # 条件2:密码长度至少9位 password_length_valid = len(password) >= 9 # 条件3:密码包含数字 has_digit = any(char.isdigit() for char in password) # 条件4:密码包含字母(大小写均可) has_letter = any(char.isalpha() for char in password) # 条件5:密码包含下划线 has_underline = '_' in password # 条件6:密码只能包含字母、数字、下划线(无其他字符) only_valid_chars = all(char.isalnum() or char == '_' for char in password) # 所有条件都满足则返回1,否则返回0 if username_valid and password_length_valid and has_digit and has_letter and has_underline and only_valid_chars: return 1 else: return 0

 (1)定义名为judgment的函数,接收两个参数:username(用户名)和password(密码),作用是校验这两个参数是否符合预设规则。

 (2)len()是 Python 内置函数,用于返回对象的长度或元素个数,在我们代码中用来判断用户名和密码是否满足系统对用户的要求

 (3)any()是 Python 内置函数,接收一个可迭代对象(如生成器、列表等),只要可迭代对象中有至少一个元素为 True,就返回 True;否则返回 False。

配合字符串方法使用:

  • char.isdigit():字符串的方法,判断单个字符char是否是数字(0-9)
  • char.isalpha():字符串的方法,判断单个字符char是否是字母(大小写均可,a-z/A-Z)

(4)in是 Python 的成员运算符,用于判断某个元素是否存在于序列(如字符串、列表)中:

  • '_' in password:检查下划线_是否在密码字符串里,存在则返回 True,否则 False。

(5)all()是 Python 内置函数,接收一个可迭代对象,只有当可迭代对象中所有元素都为 True时,才返回 True;否则返回 False。

  • char.isalnum():字符串的方法,判断单个字符char是否是字母或数字(即a-z/A-Z/0-9);

   代码通过 Python 内置函数(len()/any()/all())、字符串方法(isdigit()/isalpha()/isalnum())和运算符(in/and),实现了对用户名(长度 > 6)和密码(长度≥9、含数字 / 字母 / 下划线、无非法字符)的多维度校验。

# 注册接口 @app.post('/user/register') #注册接口需要获取客户端传来的username和password(通过 URL 查询参数),而这些数据都封装在Request对象里 ——FastAPI 会自动把当前请求的Request实例传给这个参数,你就能通过它拿到请求数据了。 def register(request: Request): username = request.query_params['username'] password = request.query_params['password'] for i in user_datas: if i['username'] == username : return {"result":"注册失败:用户名重复"} if judgment(username, password): user_data = { "username": username, "password": password, } user_datas.append(user_data) print(user_datas) return {"result":f"注册成功:{username}成功注册"} else: return {"result":"注册失败:注册的用户名和密码未满足要求"}

(1)@app.post('/user/register')是 FastAPI 的装饰器,作用是:

  • 告诉 FastAPI:“当有人用 POST 方法访问/user/register路径时,就执行下面的register函数”;
  • 装饰器是 Python 的语法糖,本质是给函数 “加功能”—— 不用装饰器的话,你得手动写代码判断请求方法和路径,麻烦到爆炸!

(2)后端 FastAPI 中的request.query_params,就是专门用来解析 URL 中 “查询参数部分”(即?后面的键值对)的工具。它的底层逻辑是:

  1. 当后端服务器收到 HTTP (这里指前端代码注册部分)请求时,会先解析请求行中的 URL,提取出?后面的字符串(比如username=testuser&password=test_123456);
  2. 按照&分割成多个键值对,再按=分割每个键值对,最终转换成一个字典结构;
  3. FastAPI 把这个字典封装成request.query_params,所以你能通过request.query_params['username']拿到前端传的用户名。

(3)FastAPI 会自动把函数的return值转换成 JSON 格式(比如return {"result": "注册成功"}会变成{"result":"注册成功"}的 JSON 字符串),再通过 HTTP 响应返回给前端。如果忘记写return,FastAPI 会默认返回 “空响应”—— 前端就拿不到数据了!

if __name__ == '__main__': uvicorn.run("main:app",host="127.0.0.1",port=8000)
  • (1)if __name__ == '__main__':Python 的特殊判断 —— 只有当这个文件被直接运行(比如右键点击 “运行”)时,才执行下面的代码;如果被其他文件导入(比如import main),这部分代码不会执行(避免重复启动服务)。
  • (2)uvicorn.run(...):启动 Uvicorn 服务器,参数说明:"main:app":指定要运行的 FastAPI 应用 ——main是当前文件名(如果文件名叫app.py,这里就是app:app),app是我们创建的 FastAPI 实例名;host="127.0.0.1":指定服务绑定的 IP 地址(127.0.0.1代表 “本机”,只有自己能访问;如果想让局域网其他设备访问,可改为0.0.0.0);port=8000:指定服务监听的端口号(就像餐厅的窗口编号,前端要通过这个端口找到服务)。

3.前后端交互的 “底层逻辑总结”

(1)协议是桥梁:前后端靠 HTTP 协议沟通,就像顾客和厨房靠服务员沟通 —— 都得按 “规矩” 来(比如 POST/GET 方法、JSON 格式);

(2)数据是核心:前端传 “需求数据”(用户名密码),后端返 “结果数据”(注册成功 / 失败),数据格式要统一(JSON 最常用);

(3)校验是保障:前端校验让用户少等,后端校验防 “坏人捣乱”;

(4)状态码是信号:200 = 成功,400 = 用户输错了,500 = 后端代码错了 —— 看状态码能快速定位问题。

三,完整代码展视

我们首先在PyCharm上创建俩个.py文件——main,py,test.py

main.py(项目后端):

import uvicorn from fastapi import FastAPI,Request app = FastAPI() user_datas = [ { "username": "admin123", "password": "admin_123", }] # 用户名、密码判断函数 def judgment(username, password): if len(username)>6 and re.match(r'^(?=.*\d)(?=.*[a-zA-Z])(?=.*_)[a-zA-Z0-9_]{9,}$',password): return 1 else: return 0 # 注册功能 @app.post('/user/register') def register(request: Request): username = request.query_params['username'] password = request.query_params['password'] for i in user_datas: if i['username'] == username : return {"result":"注册失败:用户名重复"} if judgment(username, password): user_data = { "username": username, "password": password, } user_datas.append(user_data) print(user_datas) return {"result":f"注册成功:{username}成功注册"} else: return {"result":"注册失败:注册的用户名和密码未满足要求"} # 登录功能 @app.post('/user/login') def login(request: Request): username = request.query_params['username'] password = request.query_params['password'] if judgment(username, password): for i in user_datas: if i['username'] == username and i['password'] == password: return {'result':f"登录成功:{username}欢迎"} return {"result":f"登录失败:用户名或密码错误"} else: return {'result':'登录失败:用户名或密码输入不正确'} # 查看用户账号信息 @app.post('/user/logout') def logout(): return user_datas # 鼠标右键启动,无需进入终端命令行 if __name__ == '__main__': uvicorn.run("main:app",host="127.0.0.1",port=8000)

main.py文件整体运行流程:

当你右键运行后端文件后:先导入模块(uvicorn、FastAPI、Request)→创建 app 实例→初始化模拟数据库 user_datas→定义校验函数 judgment;启动 Uvicorn 服务器,绑定 127.0.0.1:8000,开始 “监听” 前端请求;

当前端发送 POST 请求到http://127.0.0.1:8000/user/register?username=xxx&password=xxx时:FastAPI 匹配到/user/register接口对应的 register 函数;自动封装请求数据为 Request 对象,传入 register 函数;函数内提取参数→遍历检查用户名是否重复→调用 judgment 校验规则→返回 JSON 结果;

当前端发送 POST 请求到http://127.0.0.1:8000/user/login?username=xxx&password=xxx时:FastAPI 匹配到/user/login接口对应的 login 函数;封装请求数据为 Request 对象,传入 login 函数;提取参数→调用 judgment 校验格式→遍历匹配账号密码→返回 JSON 结果;

当前端发送 POST 请求到http://127.0.0.1:8000/user/logout时:FastAPI 匹配到/user/logout接口对应的 logout 函数;直接返回 user_datas 列表作为 JSON 结果;

服务器持续运行,直到你手动停止(比如按 Ctrl+C)。

test.py(项目前端):

import requests while True: user_input = input('1、注册\n2、登录\n3、查看\n4、退出\n请输入你要进行的操作:') if user_input == '1': user = input("用户名:") password = input("密码:") res = requests.post('http://127.0.0.1:8000/user/register',params={"username":user,"password":password}) result = res.json() print(f"{result["result"]}") elif user_input == '2': user = input("用户名:") password = input("密码:") res = requests.post('http://127.0.0.1:8000/user/login', params={"username": user, "password": password}) result = res.json() print(f"{result["result"]}") elif user_input == '3': res = requests.post('http://127.0.0.1:8000/user/logout') result = res.json() print(f"{result}") elif user_input == '4': break else: print("输入的操作错误请重新输入")

test.py文件整体运行流程:

  1. 程序启动→导入 requests→定义后端接口列表→进入无限循环;
  2. 打印菜单→用户输入指令→按指令分支处理:
    • 注册 / 登录:收集账号密码→发 POST 请求→解析响应→展示结果;
    • 查看:直接发请求→解析用户列表→展示;
    • 退出:结束程序;
  3. 若输入错误,提示后重新等待输入。
前后端联动整体运行流程总结

当你先启动后端文件,再启动前端文件后:后端:导入模块→创建 app 实例→初始化数据库→定义校验函数→启动 Uvicorn 监听 8000 端口;前端:导入 requests→定义接口列表→进入 while 循环打印操作菜单;

当用户在前端输入 “1” 选择注册时:前端接收用户名 / 密码→发送 POST 请求到后端注册接口(带 URL 参数);后端接收请求→校验用户名唯一性→校验规则→返回结果;前端解析 JSON 响应→打印注册结果→回到菜单循环;

当用户在前端输入 “2” 选择登录时:前端接收用户名 / 密码→发送 POST 请求到后端登录接口(带 URL 参数);后端接收请求→校验格式→匹配账号密码→返回结果;前端解析 JSON 响应→打印登录结果→回到菜单循环;

当用户在前端输入 “3” 选择查看时:前端发送 POST 请求到后端 logout 接口;后端返回所有用户数据;前端解析 JSON→打印用户列表→回到菜单循环;

当用户输入 “4” 时,前端跳出循环结束运行,后端保持监听直到手动停止。

前后端数据传递类型

后端代码里,返回的是 Python 的字典(dict)或列表(list):

  • 注册 / 登录接口返回的是{"result": "..."}(Python 字典);
  • /user/logout接口返回的是user_datas(Python 列表)。

FastAPI 会自动将这些 Python 原生类型(dict、list、str、int 等)序列化为 JSON 字符串,再通过 HTTP 响应返回 —— 你不需要手动转 JSON,FastAPI 帮你做了序列化。

前端代码里,用res.json()方法,会把后端返回的 JSON 字符串反序列化为 Python 的字典或列表(这一步叫 “反序列化”)。比如:

  • 后端返回的 JSON 字符串"{\"result\":\"注册成功...\"}",经res.json()解析后,变成 Python 的dict类型:{"result": "注册成功..."}
  • 后端返回的用户列表 JSON 字符串,解析后变成 Python 的list类型:[{"username": "admin123", "password": "admin_123"}]

Read more

数据结构-7.Java. 对象的比较

数据结构-7.Java. 对象的比较

本篇博客给大家带来的是java对象的比较的知识点, 其中包括 用户自定义类型比较, PriorityQueue的比较方式, 三种比较方法...... 文章专栏: Java-数据结构 若有问题 评论区见 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 1. PriorityQueue中插入对象 上篇文章我们介绍了优先级队列,优先级队列在插入元素时有个要求:插入的元素不能是null或者元素之间必须要能够 进行比较,为了简单起见,我们只是插入了Integer类型,那优先级队列中能否插入自定义类型对象呢? class Card { public int rank; // 数值 public String suit; // 花色 public Card(int rank, String suit) { this.rank = rank; this.suit = suit; } } public class TestPriorityQueue

Java集成PaddlePaddle OCR:让文字识别变得如此简单

还在为Java项目中需要文字识别功能而烦恼吗?传统方案要么依赖复杂的Python环境,要么调用云端API存在延迟和安全风险。现在,通过SmartJavaAI项目,你可以轻松实现Java环境下的离线OCR识别,无需任何Python依赖! 【免费下载链接】SmartJavaAIJava免费离线AI算法工具箱,支持人脸识别(人脸检测,人脸特征提取,人脸比对,人脸库查询,人脸属性检测:年龄、性别、眼睛状态、口罩、姿态,活体检测)、目标检测(支持 YOLO,resnet50,VGG16等模型)等功能,致力于为开发者提供开箱即用的 AI 能力,无需 Python 环境,Maven 引用即可使用。目前已集成 RetinaFace、SeetaFace6、YOLOv8 等主流模型。 项目地址: https://gitcode.com/geekwenjie/SmartJavaAI 技术解密:PaddlePaddle与Java的完美融合 SmartJavaAI采用DJL(Deep

Java 大视界 -- Java 大数据机器学习模型在生物信息学基因功能预测中的优化与应用

Java 大视界 -- Java 大数据机器学习模型在生物信息学基因功能预测中的优化与应用

Java 大视界 -- Java 大数据机器学习模型在生物信息学基因功能预测中的优化与应用 * 引言: * 正文: * 一、生物信息学中基因功能预测的背景与挑战 * 1.1 基因功能预测:生命科学的 “核心拼图” * 1.2 传统方法的 “困境与挣扎” * 二、Java 大数据与机器学习模型的 “黄金搭档” 优势 * 2.1 Java 大数据:基因数据处理的 “超级引擎” * 2.2 机器学习模型:基因功能预测的 “智慧大脑” * 三、Java 大数据机器学习模型的经典应用案例 * 3.1 神经网络在人类疾病基因预测中的 “精准狙击” * 3.2 支持向量机(SVM)在植物基因功能分类中的 “智慧分拣” * 四、Java 大数据机器学习模型面临的挑战与破局之道

Java 注解与反射实战:手把手实现自定义日志与参数校验注解

Java 注解与反射实战:手把手实现自定义日志与参数校验注解

前言:为什么需要自定义注解? 在日常开发中,我们经常遇到两类重复工作: 日志记录:每个重要方法都要写 "开始执行"、"参数是 xxx"、"执行结束" 的代码;参数校验:判断输入是否为 null、年龄是否在合理范围、手机号格式是否正确等。 这些工作机械且冗余,而注解 + 反射正是解决这类问题的 "银弹"—— 用注解标记需要处理的地方,用反射自动执行逻辑,实现 "一次定义,多处复用"。 本文将带你从零实现两个实用案例: 1. 自定义日志注解@Log:自动记录方法调用细节; 2. 自定义参数校验注解@NotNull、@Range:自动校验方法参数合法性。 全程实战,代码可直接运行,搭配图解帮你吃透底层逻辑。 案例一:自定义日志注解@