当前位置: 首页 > java >正文

Django的Serializers与 fastapi 的Pydantic

您说得非常对!FastAPI 的 schemas 确实在概念和功能上类似于 Django 的序列化器(Serializers),但它们基于不同的技术栈,实现方式和使用场景有一些区别。

核心相似点

功能FastAPI Schemas (Pydantic)Django Serializers
数据验证✅ 是核心功能✅ 是核心功能
数据序列化✅ 请求/响应数据转换✅ 模型实例↔JSON转换
数据反序列化✅ JSON→Python对象✅ JSON→模型实例
字段定义✅ 定义字段类型和约束✅ 定义字段类型和约束
嵌套关系✅ 支持嵌套模型✅ 支持嵌套关系

主要区别

特性FastAPI Schemas (Pydantic)Django Serializers
技术基础基于 Pydantic基于 Django ORM
主要用途API 请求/响应验证ORM 数据序列化
与ORM关系松耦合,需要手动转换紧耦合,自动处理ORM对象
验证时机请求进入时自动验证需要显式调用 is_valid()
OpenAPI集成自动生成API文档需要额外配置

代码对比示例

1. FastAPI Schemas 示例

# schemas.py - FastAPI + Pydantic
from pydantic import BaseModel, Field, EmailStr
from typing import Optional
from datetime import datetimeclass UserCreate(BaseModel):"""创建用户的请求模型 - 类似于 Django 的 CreateSerializer"""username: str = Field(..., min_length=3, max_length=50, description="用户名")email: EmailStr = Field(..., description="邮箱")password: str = Field(..., min_length=6, description="密码")level: str = Field("粉丝", description="用户等级")class UserResponse(BaseModel):"""用户响应模型 - 类似于 Django 的 ModelSerializer"""id: intusername: stremail: strlevel: strbalance: floatcreated_at: datetimeclass Config:orm_mode = True  # 允许从ORM对象转换class UserUpdate(BaseModel):"""用户更新模型 - 类似于 Django 的 UpdateSerializer"""username: Optional[str] = Noneemail: Optional[EmailStr] = Nonelevel: Optional[str] = None

2. Django Serializers 等效实现

# serializers.py - Django
from rest_framework import serializers
from django.contrib.auth.models import User
from .models import UserProfileclass UserCreateSerializer(serializers.Serializer):"""等效于 FastAPI 的 UserCreate"""username = serializers.CharField(min_length=3, max_length=50)email = serializers.EmailField()password = serializers.CharField(min_length=6)level = serializers.CharField(default="粉丝")def create(self, validated_data):# 创建用户的逻辑passclass UserResponseSerializer(serializers.ModelSerializer):"""等效于 FastAPI 的 UserResponse"""class Meta:model = UserProfilefields = ['id', 'username', 'email', 'level', 'balance', 'created_at']class UserUpdateSerializer(serializers.ModelSerializer):"""等效于 FastAPI 的 UserUpdate"""class Meta:model = UserProfilefields = ['username', 'email', 'level']extra_kwargs = {'username': {'required': False},'email': {'required': False},'level': {'required': False}}

在 FastAPI 中的使用方式

# routers/users.py
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import Listfrom database import get_db
import models
import schemasrouter = APIRouter()@router.post("/users/", response_model=schemas.UserResponse, status_code=status.HTTP_201_CREATED)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):"""创建用户 - 自动验证输入数据"""# 检查用户是否已存在db_user = db.query(models.User).filter(models.User.username == user.username).first()if db_user:raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,detail="用户名已存在")# 创建用户(这里简化了密码哈希)db_user = models.User(username=user.username,email=user.email,password=user.password,  # 实际项目中应该哈希密码level=user.level)db.add(db_user)db.commit()db.refresh(db_user)return db_user  # 自动使用 UserResponse schema 序列化@router.get("/users/{user_id}", response_model=schemas.UserResponse)
def get_user(user_id: int, db: Session = Depends(get_db)):"""获取用户信息 - 自动使用响应模型序列化"""user = db.query(models.User).filter(models.User.id == user_id).first()if not user:raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,detail="用户不存在")return user@router.get("/users/", response_model=List[schemas.UserResponse])
def get_users(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):"""获取用户列表"""users = db.query(models.User).offset(skip).limit(limit).all()return users@router.patch("/users/{user_id}", response_model=schemas.UserResponse)
def update_user(user_id: int, user_update: schemas.UserUpdate, db: Session = Depends(get_db)):"""更新用户信息 - 部分更新"""db_user = db.query(models.User).filter(models.User.id == user_id).first()if not db_user:raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,detail="用户不存在")# 只更新提供的字段update_data = user_update.dict(exclude_unset=True)for field, value in update_data.items():setattr(db_user, field, value)db.commit()db.refresh(db_user)return db_user

高级功能对比

1. 自定义验证

FastAPI (Pydantic):

from pydantic import BaseModel, validatorclass UserCreate(BaseModel):username: strpassword: strconfirm_password: str@validator('username')def username_must_contain_letter(cls, v):if not any(c.isalpha() for c in v):raise ValueError('用户名必须包含字母')return v@validator('confirm_password')def passwords_match(cls, v, values):if 'password' in values and v != values['password']:raise ValueError('密码不匹配')return v

Django Serializers:

from rest_framework import serializersclass UserCreateSerializer(serializers.Serializer):username = serializers.CharField()password = serializers.CharField()confirm_password = serializers.CharField()def validate_username(self, value):if not any(c.isalpha() for c in value):raise serializers.ValidationError('用户名必须包含字母')return valuedef validate(self, data):if data['password'] != data['confirm_password']:raise serializers.ValidationError('密码不匹配')return data

2. 关系字段处理

FastAPI (需要手动处理):

class OrderResponse(BaseModel):id: intorder_no: stramount: floatuser: schemas.UserResponse  # 嵌套关系class Config:orm_mode = True# 在路由中需要手动处理关系加载
@router.get("/orders/{order_id}", response_model=OrderResponse)
def get_order(order_id: int, db: Session = Depends(get_db)):order = db.query(models.Order).options(joinedload(models.Order.user)).filter(models.Order.id == order_id).first()return order

Django (自动处理):

class OrderSerializer(serializers.ModelSerializer):user = UserSerializer()  # 自动处理关系class Meta:model = Orderfields = ['id', 'order_no', 'amount', 'user']

总结

方面FastAPI SchemasDjango Serializers
学习曲线较平缓,基于Python类型提示需要了解Django ORM
灵活性很高,与ORM解耦较高,但与Django紧密集成
性能较好,基于Pydantic的快速验证良好,但可能有ORM开销
文档生成自动生成OpenAPI文档需要drf-yasg等第三方包
生态系统快速增长,与现代Python栈集成成熟,与Django生态完美集成

选择建议:

  • 如果你喜欢现代Python类型提示自动API文档,选择FastAPI + Pydantic
  • 如果你已经是Django开发者或需要完整的后台管理,选择Django + DRF
  • 如果你想要最大灵活性性能,FastAPI是更好的选择
  • 如果你需要快速开发丰富的插件生态,Django可能更合适

两者都是优秀的工具,选择取决于项目需求和个人偏好。

http://www.xdnf.cn/news/18643.html

相关文章:

  • 【R语言】R语言中 rbind() 与 merge() 的区别详解
  • 网络编程-创建TCP协议服务器
  • 疏老师-python训练营-Day54Inception网络及其思考
  • 屏幕类型与信号接口
  • 【KO】前端面试一
  • LLaMA-Factory 中配置文件或命令行里各个参数的含义
  • 如何利用 DeepSeek 提升工作效率
  • 10.Shell脚本修炼手册---脚本的条件测试与比较
  • 国家自然科学基金(国自然基金)申请技巧详解
  • 深度学习入门:神经网络
  • 【2025CVPR-目标检测方向】UniMamba:基于激光雷达的3D目标检测,采用分组高效曼巴语进行统一空间信道表示学习
  • Q/DR/CX7.2-2020 是中国企业标准体系中
  • 一个备份、去除、新增k8s的node标签脚本
  • `strdup` 字符串复制函数
  • 【JVM内存结构系列】二、线程私有区域详解:程序计数器、虚拟机栈、本地方法栈——搞懂栈溢出与线程隔离
  • 奇怪的前端面试题
  • 智能系统与未来生态演进初步思考
  • LangChain4j中集成Redis向量数据库实现Rag
  • 2-4.Python 编码基础 - 流程控制(判断语句、循环语句、break 语句与 continue 语句)
  • 【Python】新手入门:Python标准库有哪些常用模块?
  • 容器安全实践(二):实践篇 - 从 `Dockerfile` 到 Pod 的权限深耕
  • 美食菜谱数据集(13943条)收集 | 智能体知识库 | AI大模型训练
  • 自学嵌入式第二十六天:数据结构-哈希表、内核链表
  • 从0开始学习Java+AI知识点总结-23.web实战案例(班级和学生增删改查、信息统计)
  • 【Prometheus】Prometheus监控Docker实战
  • C++编程语言:标准库:第36章——字符串类(Bjarne Stroustrup)
  • 【C语言16天强化训练】从基础入门到进阶:Day 8
  • Krea Video:Krea AI推出的AI视频生成工具
  • 知识蒸馏 Knowledge Distillation 序列的联合概率 分解成 基于历史的条件概率的连乘序列
  • 大模型——深度评测智能体平台Coze Studio