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

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.dtcms.com/a/348058.html

相关文章:

  • Excel 转化成JSON
  • Java:LinkedList的使用
  • Django的Settings 配置文件详解
  • 【ArcGIS Pro 全攻略】GIS 数据格式终极指南:从原理到实战,再也不纠结选哪种格式!
  • React useState 全面深入解析
  • Linux 824 shell:expect
  • 基于5G NR NTN与DVB-S2X/RCS2的机载卫星通信终端性能分析
  • 低功耗模式DMA数据搬运问题解析
  • 在测试接入抖音小游戏订阅消息推送时遇到的问题
  • bun + vite7 的结合,孕育的 Robot Admin 【靓仔出道】(十八)
  • K8s部署MySQL8.0数据库
  • Transformer实战(13)——从零开始训练GPT-2语言模型
  • 【go语言】字符串函数
  • imx6ull-驱动开发篇39——Linux INPUT 子系统实验
  • 05-ArkUI界面开发
  • Solidity学习笔记
  • ZKmall模块商城的推荐数据体系:从多维度采集到高效存储的实践
  • 用 Bright Data MCP Server 构建实时数据驱动的 AI 情报系统:从市场调研到技术追踪的自动化实战
  • 青少年软件编程(python五级)等级考试试卷-客观题(2024年6月)
  • 数据库原理及应用_数据库基础_第2章关系数据库标准语言SQL_数据的维护
  • Adobe CS6所有系列绿色免安装版,Photoshop 6 Adobe Illustrator CS6 等绿色版
  • Spring创建的方式
  • 使用 Frida 运行时检测 Android 应用的真实权限状态 (App Ops)
  • 第4章栈和队列:顺序队——基本结构
  • Java 基础学习总结(211)—— Apache Commons ValidationUtils:让参数校验从 “体力活“ 变 “优雅事“
  • Vue状态管理工具pinia的使用以及Vue组件通讯
  • 一个byte表示多个bool属性的功能
  • 高并发AI服务部署方案:vLLM、TGI、FastChat性能压测报告
  • CSS 进阶用法
  • Read View是实现MVCC的三大前提之一,那么它是在什么时候建立的