Bootstrap

【django】Django REST Framework 序列化与反序列化详解

目录

1、什么是序列化和反序列化?

2、Django REST Framework中的序列化和反序列化

3、安装与配置(第10章是从零开始)

3.1 安装

3.2 配置

4、基本使用

4.1 创建序列化器

4.2 使用序列化器(将数据序列化返回给前端)

 4.3 配置url

4.4 测试

4.5 反序列化(从前端获取数据反序列化)

4.5.1 url配置

4.5.2 测试

4.6 数据验证(将4.1的序列化设置验证方式多样化)

5、一对多模型序列化

5.1 模型定义

5.2 序列化器定义

5.3 使用序列化器

 5.4 url配置

5.5 测试

6、多对多关系

6.1 模型定义

6.2 序列化器定义

6.3 使用序列化器

6.4 url配置

6.5 测试

7、自定义字段

7.1 模型定义

7.2 序列化器定义

7.3 使用序列化器

7.4 配置url

7.5 测试

7.6 使用depth优化序列化器

8、来个多表级联

8.1 模型定义

8.2 序列化器定义

8.3 使用序列化器

8.4 配置URL

8.5 测试

9、总结

10、前期工作

10.1 创建django项目

10.2 安装库

10.3 配置

10.3.1 创建mysql数据库drf

10.3.2 配置mysql数据

10.3.3 settings配置

10.3.4 apps.py

 10.3.5 DRFDemo的urls配置

10.3.6 drf的urls配置

10.3.7 新建库表之后操作(非必须)

 10.4 同步数据库

10.5 创建超级用户

 10.6 启动服务

10.7 访问

10.7.1 后端管理页面

10.7.2 默认页面


前言:Django REST Framework 序列化与反序列化详解,包含一对一,一对多,多对多的关系。 

在当今的Web开发中,前后端分离已经成为一种趋势。在这种模式下,后端主要负责数据处理和业务逻辑,而前端则专注于用户界面和交互。为了有效地在前后端之间传输数据,通常使用JSON这种轻量级的数据交换格式。Django REST Framework(DRF)作为一个强大的Django扩展,提供了便捷的REST API开发框架,其中的序列化和反序列化功能正是实现这一传输的关键。

1、什么是序列化和反序列化?

  • 序列化:将Python对象转换为JSON或其他文本格式,以便通过HTTP进行传输。
  • 反序列化:将JSON数据转换回Python对象,以便在后端进行处理。

2、Django REST Framework中的序列化和反序列化

DRF通过序列化器(Serializer)来实现这一功能。序列化器不仅负责数据的转换,还提供了数据验证和渲染的功能。

3、安装与配置(第10章是从零开始)

3.1 安装

首先,你需要安装Django REST Framework:

pip install djangorestframework

3.2 配置

然后,在你的settings.py文件中,将rest_framework添加到INSTALLED_APPS中:

INSTALLED_APPS = [  
    ...  
    'rest_framework',  
    ...  
]

4、基本使用

4.1 创建序列化器

序列化器通常定义在应用程序下的serializers.py文件中。你可以通过继承serializers.Serializerserializers.ModelSerializer来创建自定义序列化器。

例如,假设你有一个Book模型:

from django.db import models  
  
class Book(models.Model):  
    title = models.CharField(max_length=100)  
    author = models.CharField(max_length=50)  
    publication_date = models.DateField()
    class Meta:
        managed = True
        db_table = 'book'
        verbose_name_plural = '书籍表'

你可以创建一个对应的序列化器:

from rest_framework import serializers  
from .models import Book  
  
class BookSerializer(serializers.ModelSerializer):  
    class Meta:  
        model = Book  
        fields = '__all__'  # 或者指定需要序列化的字段,如 ['title', 'author', 'publication_date']

4.2 使用序列化器(将数据序列化返回给前端)

在视图中,你可以通过实例化序列化器对象,并将要序列化的数据传递给instance参数(对于单个对象)或many=True(对于多个对象)来进行序列化。

from rest_framework.views import APIView  
from rest_framework.response import Response  
from .models import Book  
from .serializers import BookSerializer  
  
class BookListView(APIView):  
    def get(self, request, *args, **kwargs):  
        books = Book.objects.all()  
        serializer = BookSerializer(books, many=True)  
        return Response(serializer.data)

 4.3 配置url

urlpatterns = [
    # path('', views.index, name='index'),  # 定义一个根路由,指向 index 视图
    # 你可以在这里添加更多的路由
    path('books/', BookListView.as_view(), name='book-list'),
]

4.4 测试

返回数据

[
    {
        "id": 1,
        "title": "西游记",
        "author": "吴承恩",
        "publication_date": "2024-10-29"
    },
    {
        "id": 2,
        "title": "红楼梦",
        "author": "曹雪芹",
        "publication_date": "2024-10-30"
    },
    {
        "id": 3,
        "title": "水浒传",
        "author": "施耐庵",
        "publication_date": "2024-10-07"
    },
    {
        "id": 4,
        "title": "三国演义",
        "author": "罗贯中",
        "publication_date": "2024-10-11"
    }
]

4.5 反序列化(从前端获取数据反序列化)

对于反序列化,你需要将前端传来的JSON数据传递给data参数,并调用is_valid()方法进行验证。如果验证通过,你可以调用save()方法将数据存储到数据库中。 

class BookCreateView(APIView):  
    def post(self, request, *args, **kwargs):  
        serializer = BookSerializer(data=request.data)  
        if serializer.is_valid():  
            serializer.save()  
            return Response(serializer.data, status=201)  
        return Response(serializer.errors, status=400)

4.5.1 url配置

urlpatterns = [  
    path('books/', BookListView.as_view(), name='book-list'),  
    path('books/create/', BookCreateView.as_view(), name='book-create'),  # 新增的路径  
]

4.5.2 测试

现在你可以使用工具(如 Postman)来测试你的创建接口。发送一个 POST 请求到 http://localhost:8000/books/create/,并在请求体中提供书籍的数据(JSON 格式): 

{  
    "title": "Django REST Framework 序列化与反序列化详解",  
    "author": "春天的菠菜",  
    "publication_date": "2024-11-01"  
}

4.6 数据验证(将4.1的序列化设置验证方式多样化)

在序列化器中,你可以通过指定字段的验证参数(如max_lengthmin_lengthrequired等)来进行数据验证。此外,你还可以定义validate_<field_name>方法来对单个字段进行自定义验证,或者定义validate方法来对多个字段进行联合验证。

class BookSerializer(serializers.ModelSerializer):  
    title = serializers.CharField(max_length=100, min_length=5)  
  
    def validate_title(self, value):  
        if 'badword' in value.lower():  
            raise serializers.ValidationError('Title contains bad words.')  
        return value  
  
    def validate(self, attrs):  
        if attrs['author'] == 'Unknown':  
            raise serializers.ValidationError({'author': 'Author cannot be Unknown.'})  
        return attrs  
  
    class Meta:  
        model = Book  
        fields = '__all__'

5、一对多模型序列化

5.1 模型定义

class Department(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField(blank=True, null=True)

    def __str__(self):
        return self.name
    class Meta:
        managed = True
        db_table = 'department'

class Employee(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    department = models.ForeignKey(Department, on_delete=models.CASCADE)
    hire_date = models.DateField()

    def __str__(self):
        return f"{self.first_name} {self.last_name}"
    class Meta:
        managed = True
        db_table = 'employee'

5.2 序列化器定义

在序列化器中,你可以使用serializers.PrimaryKeyRelatedFieldserializers.StringRelatedField来引用关联对象的主键或字符串表示,或者使用嵌套的序列化器来表示关联对象的完整数据。

from rest_framework import serializers
from .models import Department, Employee

class DepartmentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Department
        fields = ['id', 'name', 'description']

class EmployeeSerializer(serializers.ModelSerializer):
    department = DepartmentSerializer()  # 使用嵌套的序列化器

    class Meta:
        model = Employee
        fields = ['id', 'first_name', 'last_name', 'department', 'hire_date']

 在这个例子中,EmployeeSerializer中的department字段使用了DepartmentSerializer作为嵌套序列化器,这样当序列化Employee对象时,department字段将包含完整的

;