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

掌握DRF的serializer_class:高效API开发

在 Django REST Framework(DRF)中,serializer_classGenericAPIView 或其子类视图 中用来指定序列化器(Serializer)的属性。

  • 它的主要作用是告诉视图在进行数据序列化(输出)和反序列化(接收请求数据并验证)时使用哪个 Serializer 类。

1️⃣ 基本用法

from rest_framework import serializers, generics
from myapp.models import Book# 1. 定义 Serializer
class BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['id', 'title', 'author', 'published_date']# 2. 在视图中使用 serializer_class
class BookListCreateView(generics.ListCreateAPIView):queryset = Book.objects.all()serializer_class = BookSerializer  # 指定序列化器

解释:

  • serializer_class = BookSerializer:告诉 DRF 视图使用 BookSerializer 来序列化和反序列化数据。
  • 当客户端发送 GET 请求时,DRF 会使用 BookSerializer 将查询集 queryset 转换为 JSON。
  • 当客户端发送 POST 请求时,DRF 会使用 BookSerializer 验证并保存数据。

2️⃣ 与 get_serializer_class() 的关系

serializer_class 是一个 静态属性,如果你需要根据不同情况动态返回不同的 Serializer,可以重写 get_serializer_class() 方法。

class BookView(generics.GenericAPIView):queryset = Book.objects.all()def get_serializer_class(self):if self.request.method == 'GET':from myapp.serializers import BookListSerializerreturn BookListSerializerreturn BookSerializer
  • 这样可以针对不同请求方法使用不同的序列化器,比如:

    • GET 请求使用 BookListSerializer(只显示部分字段)
    • POST 请求使用 BookSerializer(包含完整字段验证)

3️⃣ 用在 ModelViewSetViewSet

ViewSet 中同样可以使用 serializer_class

from rest_framework import viewsetsclass BookViewSet(viewsets.ModelViewSet):queryset = Book.objects.all()serializer_class = BookSerializer
  • DRF 会根据不同的动作(list/retrieve/create/update)自动使用这个 Serializer。
  • 同样可以通过重写 get_serializer_class() 来针对动作指定不同 Serializer:
class BookViewSet(viewsets.ModelViewSet):queryset = Book.objects.all()def get_serializer_class(self):if self.action == 'list':return BookListSerializerreturn BookSerializer

4️⃣ 总结

  • serializer_class 是静态属性:指定视图使用哪个 Serializer。

  • get_serializer_class() 是动态方法:可根据请求或动作返回不同的 Serializer。

  • 主要用于:

    • 数据输出序列化(queryset → JSON)
    • 数据输入验证(JSON → 模型实例)

在这里插入图片描述

ModelSerializer 详细用法

基本用法

1. 最简单的 ModelSerializer

from rest_framework import serializers
from .models import User, Postclass UserSerializer(serializers.ModelSerializer):class Meta:model = Userfields = '__all__'  # 包含所有字段

2. 指定特定字段

class UserSerializer(serializers.ModelSerializer):class Meta:model = Userfields = ['id', 'username', 'email', 'date_joined']

3. 排除特定字段

class UserSerializer(serializers.ModelSerializer):class Meta:model = Userexclude = ['password', 'is_superuser']  # 排除敏感字段

高级用法

1. 添加额外字段

class UserSerializer(serializers.ModelSerializer):# 计算字段full_name = serializers.SerializerMethodField()# 关联字段post_count = serializers.IntegerField(source='posts.count', read_only=True)class Meta:model = Userfields = ['id', 'username', 'email', 'full_name', 'post_count']def get_full_name(self, obj):return f"{obj.first_name} {obj.last_name}"

2. 嵌套序列化

class CommentSerializer(serializers.ModelSerializer):class Meta:model = Commentfields = ['id', 'content', 'created_at']class PostSerializer(serializers.ModelSerializer):# 嵌套序列化author = UserSerializer(read_only=True)comments = CommentSerializer(many=True, read_only=True)class Meta:model = Postfields = ['id', 'title', 'content', 'author', 'comments', 'created_at']

3. 字段级别自定义

class UserSerializer(serializers.ModelSerializer):email = serializers.EmailField(required=False)username = serializers.CharField(max_length=50)class Meta:model = Userfields = ['id', 'username', 'email', 'date_joined']

4. 只读字段

class UserSerializer(serializers.ModelSerializer):class Meta:model = Userfields = ['id', 'username', 'email', 'date_joined']read_only_fields = ['id', 'date_joined']  # 这些字段只读

验证和钩子方法

1. 字段级别验证

class UserSerializer(serializers.ModelSerializer):class Meta:model = Userfields = ['username', 'email', 'age']def validate_username(self, value):if 'admin' in value.lower():raise serializers.ValidationError("用户名不能包含 'admin'")return valuedef validate(self, data):if data['age'] < 18 and data['username']:raise serializers.ValidationError("未成年人需要特殊处理")return data

2. 自定义创建和更新方法

class UserSerializer(serializers.ModelSerializer):class Meta:model = Userfields = ['username', 'email', 'password']extra_kwargs = {'password': {'write_only': True}}def create(self, validated_data):# 对密码进行加密password = validated_data.pop('password')user = User(**validated_data)user.set_password(password)user.save()return userdef update(self, instance, validated_data):# 处理密码更新if 'password' in validated_data:password = validated_data.pop('password')instance.set_password(password)return super().update(instance, validated_data)

深度控制 (depth)

class PostSerializer(serializers.ModelSerializer):class Meta:model = Postfields = '__all__'depth = 1  # 自动嵌套一层关联对象

完整示例

models.py

from django.db import modelsclass User(models.Model):username = models.CharField(max_length=150, unique=True)email = models.EmailField(unique=True)password = models.CharField(max_length=128)first_name = models.CharField(max_length=30, blank=True)last_name = models.CharField(max_length=30, blank=True)date_joined = models.DateTimeField(auto_now_add=True)is_active = models.BooleanField(default=True)class Post(models.Model):title = models.CharField(max_length=200)content = models.TextField()author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')created_at = models.DateTimeField(auto_now_add=True)updated_at = models.DateTimeField(auto_now=True)is_published = models.BooleanField(default=False)

serializers.py

from rest_framework import serializers
from .models import User, Postclass UserSerializer(serializers.ModelSerializer):post_count = serializers.SerializerMethodField()full_name = serializers.SerializerMethodField()class Meta:model = Userfields = ['id', 'username', 'email', 'full_name', 'post_count', 'date_joined']read_only_fields = ['id', 'date_joined']def get_post_count(self, obj):return obj.posts.count()def get_full_name(self, obj):return f"{obj.first_name} {obj.last_name}".strip()class PostSerializer(serializers.ModelSerializer):author_name = serializers.CharField(source='author.username', read_only=True)author_email = serializers.EmailField(source='author.email', read_only=True)class Meta:model = Postfields = ['id', 'title', 'content', 'author', 'author_name', 'author_email', 'created_at', 'updated_at', 'is_published']read_only_fields = ['id', 'created_at', 'updated_at']def validate_title(self, value):if len(value) < 5:raise serializers.ValidationError("标题至少需要5个字符")return value

views.py

from rest_framework import viewsets
from .models import User, Post
from .serializers import UserSerializer, PostSerializerclass UserViewSet(viewsets.ModelViewSet):queryset = User.objects.all()serializer_class = UserSerializerclass PostViewSet(viewsets.ModelViewSet):queryset = Post.objects.all()serializer_class = PostSerializerdef perform_create(self, serializer):# 自动设置当前用户为作者serializer.save(author=self.request.user)

常用 Meta 选项

选项描述示例
model关联的Django模型model = User
fields包含的字段列表fields = ['id', 'name']
exclude排除的字段列表exclude = ['password']
read_only_fields只读字段列表read_only_fields = ['id']
extra_kwargs字段额外参数extra_kwargs = {'password': {'write_only': True}}
depth关联对象嵌套深度depth = 1

最佳实践

  1. 不要使用 fields = '__all__':明确指定字段,避免意外暴露敏感数据
  2. 处理密码字段:使用 write_only=True 和自定义创建/更新方法
  3. 验证用户输入:添加字段级别和对象级别的验证
  4. 合理使用嵌套:避免过度嵌套导致性能问题
  5. 使用 read_only_fields:保护不应该通过API修改的字段

这样使用 ModelSerializer 可以大大提高开发效率,同时保持代码的清晰和可维护性。

http://www.dtcms.com/a/344912.html

相关文章:

  • [激光原理与应用-318]:光学设计 - Solidworks - 草图中常见的操作
  • PCIe 5.0 SSD的发热量到底有多大?如何避免?
  • ubuntu - 终端工具 KConsole安装
  • DL00433-基于深度学习的无人机红外成像系统可视化含数据集
  • 【数据结构】选择排序:直接选择与堆排序详解
  • 【小白笔记】 MNN 移动端大模型部署
  • Java试题-选择题(14)
  • 新能源知识库(83)新能源行业的标准制定机构介绍
  • 期权买沽是什么意思?
  • python3GUI--Joy音乐播放器 在线播放器 播放器 By:PyQt5(附下载地址)
  • DAY01:【DL 第一弹】深度学习的概述
  • 什么是哈希值(hash value)???
  • FFmpeg03:多媒体文件处理基础
  • ffmpeg 中 crc32 源码分析及调试
  • vagrant怎么在宿主机操作虚拟机里面的系统管理和软件安装
  • xilinx的oddr原语是否可以直接使用verilog实现?
  • ingress和service区别
  • 20250822解决荣品RD-RK3588-MID核心板出现插USB开机-长按RESET开机的问题
  • 基于LangChain + Milvus 实现RAG
  • 升级 Docker Compose 到最新版本:从安装到验证全指南
  • SOLIDWORKS 2025智能工具优化设计流程
  • 数据结构: 2-3 树的删除操作 (Deletion)
  • Maven的概念与Maven项目的创建
  • 线程异步操作
  • LoRA内部原理代码解析(52)
  • 【笔记】动手学Ollama 第七章 应用案例 Agent应用
  • SpringBoot项目创建的五种方式
  • 线性回归:机器学习中的基石
  • Unreal Engine UE_LOG
  • BigData大数据应用开发学习笔记(04)离线处理--离线分析Spark SQL