Django DRF 序列化

本文链接: 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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,552评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,666评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,519评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,180评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,205评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,344评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,781评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,449评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,635评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,467评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,515评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,217评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,775评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,851评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,084评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,637评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,204评论 2 341