【Django】REST 常用类

ModelSerializer

serializers.ModelSerializer 是 Django REST framework(DRF)里的一个强大工具,它能极大简化序列化和反序列化 Django 模型实例的流程。下面从多个方面详细介绍它:

1. 基本概念

序列化是把 Django 模型实例转化为 Python 原生数据类型(像字典、列表等),进而能方便地转换为 JSON、XML 等格式用于传输;反序列化则是将接收到的数据转换回 Django 模型实例。ModelSerializer 会自动依据模型的字段定义来生成序列化器的字段,减少了手动编写序列化器字段的工作量。

2. 基本用法

假设你有一个简单的 Django 模型 Book

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()

    def __str__(self):
        return self.title

可以创建一个对应的 ModelSerializer

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

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

在上述代码里,Meta 类的 model 属性指定要序列化的模型,fields 属性指定要包含在序列化结果中的字段。

3. 常用属性和方法

Meta 类属性
  • model:指定要序列化的 Django 模型。
  • fields :指定要包含在序列化结果中的字段,可以是字段名的列表或字符串 '__all__'(表示包含模型的所有字段)。
  • exclude :指定要排除的字段,不能与 fields 同时使用。
  • read_only_fields:指定只读字段,这些字段在反序列化时会被忽略。
  • extra_kwargs :用于为特定字段提供额外的参数,例如设置字段的 requiredwrite_only 等属性。

示例:

python 复制代码
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'
        read_only_fields = ['id']
        extra_kwargs = {
            'title': {'required': True},
            'author': {'write_only': True}
        }
序列化方法
  • data:返回序列化后的 Python 原生数据类型。
python 复制代码
book = Book.objects.first()
serializer = BookSerializer(book)
print(serializer.data)
  • is_valid():验证反序列化的数据是否有效。
python 复制代码
data = {'title': 'New Book', 'author': 'John Doe', 'published_date': '2023-01-01'}
serializer = BookSerializer(data=data)
if serializer.is_valid():
    book = serializer.save()
else:
    print(serializer.errors)
  • save():保存反序列化后的数据,创建或更新模型实例。

4. 自定义序列化行为

可以通过重写序列化器的方法来自定义序列化和反序列化行为。

重写 to_representation 方法
python 复制代码
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['title'] = data['title'].upper()
        return data
重写 createupdate 方法
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.author = validated_data.get('author', instance.author)
        instance.published_date = validated_data.get('published_date', instance.published_date)
        instance.save()
        return instance

5. 优点

  • 代码简洁:自动生成序列化器字段,减少了手动编写的工作量。
  • 一致性:序列化器的字段与模型的字段保持一致,方便维护。
  • 验证功能:自动提供基本的验证功能,确保数据的有效性。

总之,serializers.ModelSerializer 是 Django REST framework 中非常实用的工具,能让你更高效地处理 Django 模型的序列化和反序列化。


在 Django REST framework(DRF)里,ModelSerializer 中的 update 方法主要用于处理更新现有模型实例的逻辑。当你使用序列化器来更新一个已存在的模型对象时,update 方法会被调用。下面为你详细介绍它的作用、工作机制以及使用示例。

作用

update 方法的核心作用是接收经过验证的数据,把这些数据应用到已有的模型实例上,并且保存更新后的实例。它是序列化器在处理 PUT 或者 PATCH 请求时的关键部分,能够帮助你定制模型实例更新的具体逻辑。

工作机制

  • 当你调用序列化器的 save 方法并且传入一个已存在的模型实例时,序列化器会自动调用 update 方法。
  • update 方法接收两个参数:
    • instance:代表要更新的模型实例。
    • validated_data:是一个字典,包含经过验证的要更新的数据。
  • update 方法内部,你可以从 validated_data 里提取数据,把这些数据赋给 instance 的相应字段,然后调用 instance.save() 方法保存更新后的实例。

示例代码

下面是一个简单的示例,展示了如何在 ModelSerializer 中重写 update 方法:

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

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

    def update(self, instance, validated_data):
        # 更新实例的字段
        instance.title = validated_data.get('title', instance.title)
        instance.author = validated_data.get('author', instance.author)
        instance.published_date = validated_data.get('published_date', instance.published_date)

        # 保存更新后的实例
        instance.save()

        return instance

代码解释

  • instance.title = validated_data.get('title', instance.title):这行代码尝试从 validated_data 中获取 title 字段的值,如果 validated_data 中存在 title 字段,就将其赋值给 instance.title;如果不存在,就保持 instance.title 的原有值。
  • instance.save():调用 save 方法将更新后的实例保存到数据库中。
  • return instance:返回更新后的实例。

自定义更新逻辑

你可以在 update 方法中添加自定义的更新逻辑,例如在更新某些字段时执行额外的操作,或者根据特定条件更新不同的字段。

python 复制代码
def update(self, instance, validated_data):
    if 'title' in validated_data:
        # 在更新标题时执行额外的操作
        new_title = validated_data['title'].upper()
        instance.title = new_title
    if 'author' in validated_data:
        # 检查作者是否合法
        if len(validated_data['author']) > 5:
            instance.author = validated_data['author']
    instance.published_date = validated_data.get('published_date', instance.published_date)
    instance.save()
    return instance

在这个例子中,当更新 title 字段时,会将新标题转换为大写;更新 author 字段时,会检查作者名字的长度是否大于 5。

综上所述,update 方法为你提供了一种灵活的方式来定制模型实例的更新逻辑,以满足特定的业务需求。


ForeignKey

在 Django 中,models.ForeignKey 是一个非常重要的字段类型,用于在模型之间创建多对一(Many-to-One)的关联关系。下面将从多个方面对其进行详细介绍。

1. 基本概念

多对一关系表示一个模型的多个实例可以关联到另一个模型的一个实例。例如,在一个博客应用中,多篇文章(Article)可以属于同一个作者(Author),那么文章和作者之间就是多对一的关系。models.ForeignKey 就是用来在 Django 模型中定义这种关系的。

2. 基本语法

python 复制代码
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Article(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

在上述代码中,Article 模型中的 author 字段是一个 ForeignKey,它指向 Author 模型。这意味着每篇文章都关联到一个作者。

3. 参数说明

to
  • 作用 :指定关联的模型。可以是模型类本身,也可以是模型类的字符串表示(如 'app_label.ModelName')。
  • 示例
python 复制代码
author = models.ForeignKey('myapp.Author', on_delete=models.CASCADE)
on_delete
  • 作用:定义当关联的对象被删除时,当前对象应该如何处理。这是一个必需的参数。
  • 常见选项
    • models.CASCADE:级联删除。当关联的对象被删除时,与之关联的所有对象也会被删除。例如,当一个作者被删除时,他所写的所有文章都会被删除。
    • models.PROTECT :保护模式。如果有关联的对象存在,不允许删除关联的对象,会抛出 ProtectedError 异常。
    • models.SET_NULL :将关联字段设置为 NULL。前提是该字段必须允许为空(null=True)。例如,当一个作者被删除时,他所写的文章的 author 字段会被设置为 NULL
    • models.SET_DEFAULT :将关联字段设置为默认值。前提是该字段必须有默认值(default=...)。
    • models.SET():将关联字段设置为指定的值或调用指定的函数返回的值。
    • models.DO_NOTHING:不做任何处理。可能会导致数据库中的外键约束错误。
  • 作用 :定义从关联模型反向查询时使用的名称。默认情况下,Django 会自动生成一个反向查询的名称,格式为 modelname_set(例如,article_set)。使用 related_name 可以自定义这个名称。
  • 示例
python 复制代码
class Article(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='articles')

现在可以通过 author.articles.all() 来获取该作者的所有文章。

null
  • 作用 :指定该字段是否可以为空。如果设置为 True,则允许该字段在数据库中存储 NULL 值。
  • 示例
python 复制代码
author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True)
blank
  • 作用 :指定在表单验证时该字段是否可以为空。如果设置为 True,则在表单中该字段可以不填写。
  • 示例
python 复制代码
author = models.ForeignKey(Author, on_delete=models.CASCADE, blank=True)

4. 反向查询

通过 ForeignKey 建立的关联关系,可以进行反向查询。例如,有了上述的 ArticleAuthor 模型,可以这样进行反向查询:

python 复制代码
author = Author.objects.get(name='John Doe')
articles = author.article_set.all()  # 如果没有指定 related_name
# 或者
articles = author.articles.all()  # 如果指定了 related_name='articles'

5. 数据库层面

在数据库中,ForeignKey 字段会被存储为一个整数,这个整数是关联模型实例的主键值。例如,Article 表中的 author 字段会存储对应的 Author 实例的 id

6. 注意事项

  • 当使用 ForeignKey 时,要确保 on_delete 参数设置合理,避免出现数据不一致的问题。
  • 频繁的级联删除可能会导致数据丢失,使用时要谨慎。

综上所述,models.ForeignKey 是 Django 中实现多对一关系的重要工具,通过合理使用其参数,可以灵活地管理模型之间的关联。


ModelViewSet

在 Django REST framework(DRF)里,viewsets.ModelViewSet 是一个强大且实用的工具,它简化了基于 Django 模型构建 RESTful API 的过程。下面我会详细讲解 viewsets.ModelViewSet 及其相关的 viewsets 模块。

1. viewsets 模块概述

viewsets 模块是 Django REST framework 提供的一组视图集类,它们把不同的视图逻辑(如列表视图、详情视图、创建视图、更新视图、删除视图等)组合在一起,让你能够以一种更简洁、高效的方式构建 API。视图集可以根据不同的 HTTP 请求方法(如 GETPOSTPUTDELETE 等)自动处理对应的操作。

2. ModelViewSet 简介

ModelViewSetviewsets 模块中的一个核心类,它继承自多个不同的混合类(如 CreateModelMixinRetrieveModelMixinUpdateModelMixinDestroyModelMixinListModelMixin),这些混合类为 ModelViewSet 提供了完整的 CRUD(创建、读取、更新、删除)操作功能。

3. 基本用法

假设你有一个简单的 Django 模型 Book

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()

    def __str__(self):
        return self.title

你可以创建一个对应的 ModelViewSet 来处理这个模型的 API 操作:

python 复制代码
from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer

class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

这里的 BookSerializer 是一个序列化器,用于将 Book 模型实例序列化为 JSON 数据,以及将 JSON 数据反序列化为 Book 模型实例。以下是一个简单的序列化器示例:

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

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

4. 路由配置

为了让 BookViewSet 能够响应 HTTP 请求,需要进行路由配置。Django REST framework 提供了 routers 模块来简化路由配置:

python 复制代码
from rest_framework import routers
from .views import BookViewSet

router = routers.DefaultRouter()
router.register(r'books', BookViewSet)

urlpatterns = router.urls

这样,BookViewSet 就会自动处理以下几种类型的请求:

  • GET /books/:获取所有书籍的列表。
  • POST /books/:创建一本新的书籍。
  • GET /books/{id}/:获取指定 ID 的书籍详情。
  • PUT /books/{id}/:更新指定 ID 的书籍的所有字段。
  • PATCH /books/{id}/:部分更新指定 ID 的书籍的字段。
  • DELETE /books/{id}/:删除指定 ID 的书籍。

5. 方法和属性

  • queryset:指定要处理的模型实例集合,通常是一个查询集(QuerySet)。
  • serializer_class:指定用于序列化和反序列化的序列化器类。
  • get_queryset():可以重写这个方法来动态地返回不同的查询集,例如根据用户权限过滤数据。
python 复制代码
class BookViewSet(viewsets.ModelViewSet):
    serializer_class = BookSerializer

    def get_queryset(self):
        # 只返回已发布的书籍
        return Book.objects.filter(published=True)
  • perform_create():可以重写这个方法来在创建新实例时执行额外的操作,例如记录日志。
python 复制代码
class BookViewSet(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def perform_create(self, serializer):
        # 在创建书籍时记录日志
        print(f"Creating a new book: {serializer.validated_data['title']}")
        serializer.save()

6. 优点

  • 代码简洁 :通过继承 ModelViewSet,可以用很少的代码实现完整的 CRUD 操作,减少了重复代码。
  • 可维护性高:将不同的视图逻辑封装在一个类中,使得代码结构更加清晰,易于维护和扩展。
  • 自动生成路由 :结合 routers 模块,可以自动生成 API 的路由,简化了路由配置。

综上所述,viewsets.ModelViewSet 是 Django REST framework 中一个非常实用的工具,能够帮助你快速、高效地构建功能完整的 RESTful API。

相关推荐
全栈前端老曹7 小时前
【MongoDB】深入研究副本集与高可用性——Replica Set 架构、故障转移、读写分离
前端·javascript·数据库·mongodb·架构·nosql·副本集
R1nG8637 小时前
CANN资源泄漏检测工具源码深度解读 实战设备内存泄漏排查
数据库·算法·cann
阿钱真强道7 小时前
12 JetLinks MQTT直连设备事件上报实战(继电器场景)
linux·服务器·网络·数据库·网络协议
逍遥德7 小时前
Sring事务详解之02.如何使用编程式事务?
java·服务器·数据库·后端·sql·spring
笨蛋不要掉眼泪8 小时前
Redis哨兵机制全解析:原理、配置与实战故障转移演示
java·数据库·redis·缓存·bootstrap
Coder_Boy_8 小时前
基于SpringAI的在线考试系统-整体架构优化设计方案
java·数据库·人工智能·spring boot·架构·ddd
fen_fen16 小时前
Oracle建表语句示例
数据库·oracle
砚边数影18 小时前
数据可视化入门:Matplotlib 基础语法与折线图绘制
数据库·信息可视化·matplotlib·数据可视化·kingbase·数据库平替用金仓·金仓数据库
orange_tt18 小时前
Djiango配置Celery
数据库·sqlite
云小逸19 小时前
【nmap源码学习】 Nmap网络扫描工具深度解析:从基础参数到核心扫描逻辑
网络·数据库·学习