首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >​从入门到"精通"Django REST Framework-(三)

​从入门到"精通"Django REST Framework-(三)

原创
作者头像
rxg456
发布2025-02-26 22:03:00
发布2025-02-26 22:03:00
7771
举报

一. 什么是 ModelSerializer?

ModelSerializer 是 Django REST Framework(DRF)提供的一个序列化器,它用于简化与 Django 模型的交互。ModelSerializer 通过自动读取 Django 模型的字段,生成对应的序列化字段,从而简化了手动编写字段的工作。它继承自 serializers.Serializer,但不同的是,它专门用于处理与 Django ORM 模型的数据交互。

二. 为什么要使用 ModelSerializer

  1. 简化代码ModelSerializer 通过自动从 Django 模型生成字段,避免了手动逐一定义每个字段的重复代码。它大大简化了序列化器的编写工作。
  2. 自动化操作ModelSerializer 提供了默认的 create()update() 方法,这些方法会自动根据模型的数据进行创建和更新。这意味着你不需要手动编写这些方法,减少了出错的概率。
  3. 与 Django ORM 紧密集成: ModelSerializer 与 Django 的 ORM 数据模型集成非常紧密,能够直接操作 Django 数据库模型,并且支持字段验证和嵌套序列化。自动继承 Model 的字段约束(如 max_length, null, unique 等)。
  4. 提高开发效率: 使用 ModelSerializer,开发人员无需手动定义字段和验证器,也无需重写 create()update() 方法,适合标准的 CRUD 操作,提升开发效率。

三. 基础用法

ModelSerializer 是为 Django 模型专门设计的序列化器,下面是基础的使用方法。

1. 定义 Django 模型

代码语言:python
复制
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    published_date = models.DateField()
    isbn_number = models.CharField(max_length=13)

2. 创建 ModelSerializer

代码语言:python
复制
from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book  # 指定模型
        fields = '__all__'  # 包含所有字段

3. 使用ModelSerializer来序列化数据

代码语言:python
复制
# 进行数据的序列化
book = Book.objects.first()
serializer = BookSerializer(book)
print(serializer.data)  # 输出序列化后的数据

四. 核心配置 Meta 类详解

ModelSerializer 中最重要的部分是 Meta 类,以下是 Meta 类常见字段及其用法。

1. model

  • 作用:指定要与序列化器关联的 Django 模型。
  • 示例
代码语言:python
复制
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book

2. fields

  • 作用:指定需要序列化的字段,可以是一个字段列表,或者 '__all__',表示包含所有字段。
  • 示例
代码语言:python
复制
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['title', 'author']  # 只序列化 title 和 author 字段

3. exclude

  • 作用:排除不需要序列化的字段,不能与 fields 一起使用。
  • 示例
代码语言:python
复制
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        exclude = ['isbn_number']  # 排除 isbn_number 字段

4. read_only_fields

  • 作用:指定只读字段,这些字段不能被更新或创建。
  • 示例
代码语言:python
复制
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        read_only_fields = ['isbn_number', 'published_date']

5. write_only_fields

  • 作用:指定只写字段,不能通过序列化器读取这些字段。
  • 示例
代码语言:python
复制
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        write_only_fields = ['password']  # 仅用于写入

6. depth

  • 作用:指定嵌套序列化的深度。如果模型之间存在外键关系,可以设置 depth 来控制递归序列化的深度。
  • 示例
代码语言:python
复制
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        depth = 1  # 递归序列化嵌套对象(如外键)

7. validators

  • 作用:为模型或字段指定验证器,进行自定义验证。
  • 示例
代码语言:python
复制
def validate_title(value):
    if 'banned' in value:
        raise serializers.ValidationError("Title contains banned words.")
    return value

class BookSerializer(serializers.ModelSerializer):
    title = serializers.CharField(validators=[validate_title])
    class Meta:
        model = Book
        fields = ['title', 'author']

五. 高级技巧

嵌套序列化

对于有外键关系的模型,可以使用嵌套序列化器进行序列化。例如,如果 Book 模型有一个指向 Author 模型的外键,可以在 BookSerializer 中嵌套 AuthorSerializer

代码语言:python
复制
class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = Author
        fields = ['name']

class BookSerializer(serializers.ModelSerializer):
    author = AuthorSerializer()
    class Meta:
        model = Book
        fields = ['title', 'author']

自定义 create()update() 方法

如果需要自定义创建和更新逻辑,可以重写 create()update() 方法。

代码语言:python
复制
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

    def create(self, validated_data):
        # 自定义创建逻辑
        return Book.objects.create(**validated_data)

    def update(self, instance, validated_data):
        # 自定义更新逻辑
        instance.title = validated_data.get('title', instance.title)
        instance.save()
        return instance

批量更新

如果需要批量更新数据,可以通过序列化器的 update() 方法配合 many=True 来实现。

代码语言:python
复制
books = Book.objects.all()
serializer = BookSerializer(books, many=True)
# 更新逻辑

六. 常见问题

如何处理外键和多对多关系的序列化?

使用嵌套的 ModelSerializer 来处理外键关系(ForeignKey),可以通过 depth 或者手动嵌套序列化器来实现多对多关系。

如何排除模型中的某些字段?

使用 exclude 来排除不需要序列化的字段。

如何验证一个字段?

通过定义 validate_<field_name> 方法来为字段添加自定义验证逻辑。

如何让字段只读?

使用 read_only_fieldsMeta 类中标记字段为只读。

七. 生产技巧

1.性能优化

  • 对于大数据量的序列化,尽量避免使用深度过大的嵌套序列化,可以使用 depth 控制递归深度,或者使用自定义嵌套序列化器来减少不必要的嵌套。
  • 使用 select_relatedprefetch_related 预加载外键和多对多关系,避免 N+1 查询问题。

2.使用 ModelSerializer 优化 API 性能:

  • 在处理批量数据时,尽量批量创建或更新数据(例如使用 bulk_createbulk_update)。
  • 对于常用字段,可以通过缓存优化性能。
批量创建数据
代码语言:python
复制
from rest_framework import serializers
from django.db import transaction

class ProductBulkSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['name', 'price', 'category']

    @transaction.atomic
    def create(self, validated_data):
        # 原生批量创建(跳过 ModelSerializer 的单个创建逻辑)
        objs = [Product(**item) for item in validated_data]
        return Product.objects.bulk_create(objs)

# 使用方式
data = [{'name': 'A', 'price':10}, {'name':'B', 'price':20}]
serializer = ProductBulkSerializer(data=data, many=True)
serializer.is_valid(raise_exception=True)
serializer.save()
批量更新数据
代码语言:python
复制
class ProductBulkUpdateSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(required=True)

    class Meta:
        model = Product
        fields = ['id', 'price', 'stock']

    def update(self, instance, validated_data):
        # 原生批量更新(需配合视图逻辑)
        update_objs = []
        for item in validated_data:
            obj = Product.objects.get(id=item['id'])
            obj.price = item['price']
            update_objs.append(obj)
        Product.objects.bulk_update(update_objs, ['price'])
        return update_objs

3.动态修改字段required属性

  • POST请求:需要提供所有字段的值
  • PATCH请求:动态修改字段属性,允许只更新需要修改的字段
代码语言:python
复制
from rest_framework import serializers

class DynamicRequiredFieldsMixin:
    def get_fields(self):
        fields = super().get_fields()
        request = self.context.get('request', None)
        
        # 仅当请求方法为 PATCH 时调整必填性
        if request and request.method in ['PATCH']:
            for field_name, field in fields.items():
                field.required = False  # 所有字段变为可选
                field.allow_null = True # 允许传入 null(可选)
        return fields

# 使用示例
class ProductSerializer(DynamicRequiredFieldsMixin, serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = '__all__'
关键原理剖析
  1. Hook 机制
    • 通过重写 get_fields() 方法,在序列化器初始化时动态修改字段属性
    • 执行顺序:get_fields() → 字段实例化 → 验证逻辑
  2. 请求上下文获取
    • self.context['request'] 获取当前请求对象
    • 需确保视图将 request 传递到序列化器上下文中(通常自动处理)
  3. 字段属性动态修改

属性

作用

示例值

required

控制字段是否必须传入

False

allow_null

允许接收 null 值(需数据库允许)

True

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一. 什么是 ModelSerializer?
  • 二. 为什么要使用 ModelSerializer
  • 三. 基础用法
    • 1. 定义 Django 模型
    • 2. 创建 ModelSerializer
    • 3. 使用ModelSerializer来序列化数据
  • 四. 核心配置 Meta 类详解
    • 1. model
    • 2. fields
    • 3. exclude
    • 4. read_only_fields
    • 5. write_only_fields
    • 6. depth
    • 7. validators
  • 五. 高级技巧
    • 嵌套序列化
    • 自定义 create() 和 update() 方法
    • 批量更新
  • 六. 常见问题
    • 如何处理外键和多对多关系的序列化?
    • 如何排除模型中的某些字段?
    • 如何验证一个字段?
    • 如何让字段只读?
  • 七. 生产技巧
    • 1.性能优化
    • 2.使用 ModelSerializer 优化 API 性能:
      • 批量创建数据
      • 批量更新数据
    • 3.动态修改字段required属性
      • 关键原理剖析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档