目录
2、Django REST Framework中的序列化和反序列化
前言: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.Serializer
或serializers.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_length
、min_length
、required
等)来进行数据验证。此外,你还可以定义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.PrimaryKeyRelatedField
或serializers.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
字段将包含完整的