Django DRF 序列化

2020-05-06  本文已影响0人  运维开发_西瓜甜

本文链接: https://www.jianshu.com/p/a7f36932dc97

一、 Serialization (序列化)

image.png

序列化官方教程

DRF 的 Serialization 和 Django 的 form 的编程思想几乎一致,假如对 form 很了解的话,学习 DRF 其实很简单。

DRF 的序列化同样有支持独立自定义字段的 Serializer 和基于 ModelModelSerializer

1.Serializer

serializers 比较适合对独立于 model 的自定义字段的序列化。

比如,修改密码功能中,要求输出两次密码的校验,model 中之会存一个字段,假如校验两次密码输入是否一致,就可以使用 serializers


① 创建一个用于序列化数据的类

创建序列化数据的类需要继承
rest_framework.serializers.Serializer

image.png
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, email, 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

image.png

④ 重启 Django 进程,在浏览器中测试

image.png

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"),
]

④ 重启 Django 进程,在浏览器中测试

image.png image.png
上一篇下一篇

猜你喜欢

热点阅读