一、 Serialization (序列化)
序列化官方教程
DRF 的 Serialization 和 Django 的 form 的编程思想几乎一致,假如对 form 很了解的话,学习 DRF 其实很简单。
DRF 的序列化同样有支持独立自定义字段的 Serializer
和基于 Model 的 ModelSerializer
1.Serializer
serializers
比较适合对独立于 model 的自定义字段的序列化。
比如,修改密码功能中,要求输出两次密码的校验,model 中之会存一个字段,假如校验两次密码输入是否一致,就可以使用 serializers
。
① 创建一个用于序列化数据的类
创建序列化数据的类需要继承
rest_framework.serializers.Serializer
from rest_framework import serializers
class UsersSerializer(serializers.Serializer):
username = serializers.CharField(
required=True, max_length=150)
email = serializers.EmailField(
required=False, allow_null=True )
password = serializers.CharField(
required=True, max_length=128)
last_login = serializers.DateTimeField(
required=False, allow_null=True)
image = serializers.ImageField(
default='users/no-image.jpg', max_length=128)
这里有文件图片的字段,需要在
settings.py
中设置如下内容MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = "/media/"
② 视图中使用序列化的类
示例 model
class UsersProfile(AbstractUser):
nick_name = models.CharField('昵称', max_length=64, default='')
birday = models.DateField('生日', null=True, blank=True)
gender = models.CharField('性别', max_length=6, choices=(('1','男'),('0','女')), default='1')
address = models.CharField('地址', max_length=128, default='')
mobile = models.CharField('手机', max_length=11)
image = models.ImageField('头像', upload_to="users/%Y/%m", default='users/no-image.jpg', max_length=128)
这里 model 显然继承了 Django 自带的
AbstractUser
,
所以会有以下字段:
username
,password
,last_login
视图
需要继承
rest_framework.views.APIView
from rest_framework.response import Response
from rest_framework.views import APIView
# 导入自定义的序列化类
from .serializers import UsersSerializer
# 导入 model
from users.models import UsersProfile
# 编写视图,继承 APIView
class UsersProfileAPIView(APIView):
def get(self, request):
users = UsersProfile.objects.all()
users_serializer = UsersSerializer(users, many=True)
return Response(users_serializer.data)
当序列化的数据是一组查询集时,需要添加参数
many=True
③ 添加 URL
④ 重启 Django 进程,在浏览器中测试
2. ModelSerializer
当需要序列化的数据是 Model 中的某些字段时,ModelSerializers
可以让事情变得超简单。
示例 model
# 服务器表
class Server(models.Model):
hostname = models.CharField(verbose_name='主机名', max_length=128, unique=True)
manage_ip = models.GenericIPAddressField(verbose_name='管理 IP', null=True, blank=True)
latest_date = models.DateTimeField(verbose_name='更新时间', default=timezone.now, null=True)
create_at = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
# 硬盘表
class Disk(models.Model):
slot = models.CharField(verbose_name='插槽位', max_length=8)
model = models.CharField(verbose_name='磁盘型号', max_length=32)
capacity = models.FloatField(verbose_name='磁盘容量GB')
pd_type = models.CharField(verbose_name='接口类型', max_length=32)
server_obj = models.ForeignKey(
Server, related_name='disk',
verbose_name='所属服务器', on_delete=models.CASCADE)
① 创建基于 Model 的序列化类
需要继承
rest_framework.serializers.ModelSerializer
from rest_framework import serializers
from cmdb.models import Server, Disk
class ServerSerializer(serializers.ModelSerializer):
class Meta:
model = Server
fields = ['hostname', 'manage_ip', 'latest_date', 'create_at']
class DiskSerializer(serializers.ModelSerializer):
# 这里可以实现在 硬盘信息中含有对应服务器的详细信息
server_obj = ServerSerializer()
class Meta:
model = Disk
fields = ['slot', 'model','capacity',
'pd_type',
'server_obj']
② 视图中使用
from rest_framework.response import Response
from rest_framework.views import APIView
from .serializers import ServerSerializer, DiskSerializer
from cmdb.models import Server, Disk
class ServerAPIView(APIView):
def get(self, request):
servers = Server.objects.all()
servers_serializer = ServerSerializer(servers, many=True)
return Response(servers_serializer.data)
class DiskAPIView(APIView):
def get(self, request):
disks = Disk.objects.all()
disks_serializer = DiskSerializer(disks, many=True)
return Response(disks_serializer.data)
③ 配置 URL
from django.urls import path
from . import views
app_name = "api"
urlpatterns = [
...
path('servers/',
views.ServerAPIView.as_view(),
name="servers"),
path('disks/',
views.DiskAPIView.as_view(),
name="disks"),
]