【DRF】Django Rest Framework(3.DRF的序列化器-serializers.Serializer详解)

本文介绍了Django中的序列化器Serializer的作用,它用于将模型数据转换为JSON格式,便于API接口返回。通过示例展示了如何创建模型、序列化器以及使用APIView进行数据的增删改查操作,强调了数据校验和序列化过程中涉及的关键步骤,如source属性的使用和序列化器的save操作。同时,文章提到了RESTful接口的常用规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、序列化器-Serializer 是什么?

简单来说,我们从数据库取出来的数据做一个json的处理,其实这就叫序列化。
就是把模型类数据,或者querySet数据转化成json的过程,就是序列化

二、通过举例来,说明 序列化器-Serializer

1. 首先创建好模型类,并连接上数据库

(1).新建一个 app,sers
(2).创建一个模型类,(为了方便默认就使用sqlite)
from django.db import models


# Create your models here.
class Book(models.Model):
    title = models.CharField(max_length=32, verbose_name='书籍名称')
    price = models.IntegerField(verbose_name='价格')
    pub_date = models.DateField(verbose_name='出版日期')

(3). python manage.py makemigrations
(4). python manage.py migrate
(5). python manage.py shell (使用shell插入两条数据)

在这里插入图片描述

2. 对单个数据进行 增删改查(全部)查(单个)

(1). 设置好路由

在这里插入图片描述

(2). 首先,查找所有书籍,这块要就要 “对数据库查询的数据进行序列化”
from django.http import HttpResponse
from django.shortcuts import render
from rest_framework.views import APIView
from sers.models import Book

from rest_framework import serializers
from rest_framework.response import Response

# 针对模型,设计序列化器
class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=32)
    price = serializers.IntegerField()
    date = serializers.DateField(source='pub_date')


class BookView(APIView):

    # 查
    def get(self, request):
        # 获取所有的书籍
        book_list = Book.objects.all()
        # 构建序列化器对象    BookSerializers(instance=,data=,many=)
        # instance,是用来做序列化器的
        # data,是用来做反序列化器的
        # many, 序列化的是一个模型类对象还是多个模型类对象, True/Falseid
        serializer = BookSerializers(instance=book_list, many=True)
        return Response(serializer.data)

因为我们通过从模型类查询的数据,是一个querySet对象或者模型类对象,这块进行序列化并不是很简单了
所以要基于DRF的序列化器,实现一个灵活并且强大的序列化过程
使用Postman调用接口,请求后发现,就会把数据打包成,OrderedDict一个有序字典,
在这里插入图片描述

(3). 使用DRF的Response响应类

DRF响应类,会根据序列化的结果处理成一个json的Content-Type,返回给客户端
使用后如下图:
在这里插入图片描述

3. 序列化器的解析的过程

(1). 解析过程
  • many=True,则说明,是一个大列表,里面有多个对象
  • 则先创建一个空列表,比如说: temp=[]
  • 最后会循环刚才传入的从模型类中查到结果列表,即本文的book_list
for obj in book_list:
    d = {}
    # 可以灵活的取决序列化那些字段,如下
    d['title'] = obj.title
    d['price'] = obj.price
    d['pub_date'] = obj.pub_date
    temp.append(d)
  • 结果就是,一个列表套有多个数据,就是多个字典,即, [{},{},{}…]
(2). 当模型类的字段名成,返回给前端时,字段名称需要修改,则,在序列化器中使用source属性

如下

date = serializers.DateField(source='pub_date')

结果:
在这里插入图片描述

4. 举例restful接口的简单规则

  • /book/ GET 查看所有资源,返回所有资源
  • /book/ POST 添加资源,返回添加的资源
  • /book/1 GET 查看某个资源,返回这一个资源
  • /book/1 PUT 编辑某个资源,返回这编辑之后的这个资源
  • /book/1 DELETE 删除某个资源,返回空

5. POST,添加资源(反序列化)

(1). 添加一本书,postman发送这个post请求,对应的view改怎么写

在这里插入图片描述

(2). 上述的带的参数,获取到数据

request.data

(3). 序列化器,里面定义的类型、以及参数,例如max_length,这块就是做数据校验用的
  • required=False, 可以不用传,默认是True
  • 注意,序列化器的类型,参数,最好要与模型类保持一致
# 针对模型,设计序列化器
class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=32)
    price = serializers.IntegerField()
    date = serializers.DateField(source='pub_date')
(4). 数据校验 serializer.is_valid() 返回一个布尔值,所有字段都符合才返回True,反之,返回False
不符合数据的都放在,serializer.errors
def post(self, request):
    # 获取参数
    data = request.data

    #  构建序列化器对象
    serializer = BookSerializers(data=data)

    # 校验数据
    # 校验原理:
    # 1.所有符合的数据都放在,serializer.validated_data
    # 2.不符合数据的都放在,serializer.errors
    if serializer.is_valid():   # 返回一个布尔值,所有字段都符合才返回True,反之,返回False
        # 数据校验通过
        pass
    else:
        # 数据校验失败
        return Response(serializer.errors)
  • 例如我,title搞一个长度特别长的,但我序列化器里面最长就32,这块校验就会报具体的错误信息
    在这里插入图片描述
所有符合的数据都放在,serializer.validated_data

当校验通过,然后返回添加的数据

def post(self, request):
    # 获取参数
    data = request.data

    #  构建序列化器对象
    serializer = BookSerializers(data=data)

    # 校验数据
    # 校验原理:
    # 1.所有符合的数据都放在,serializer.validated_data
    # 2.不符合数据的都放在,serializer.errors
    if serializer.is_valid():   # 返回一个布尔值,所有字段都符合才返回True,反之,返回False
        # 数据校验通过,存入数据库中
        new_book = Book.objects.create(**serializer.validated_data)
        return Response(serializer.data)
    else:
        # 数据校验失败
        return Response(serializer.errors)

使用postman调用之后,的结果
在这里插入图片描述

三、序列化器的的save操作

1.一般情况往数据库里面插数据

Book.objects.create(**serializer.validated_data)
最好用 一个函数,包含起来,然后调用这个函数进行保存,如下

2. 使用序列化器进行保存数据

(1)使用序列化器对象的save()方法

serializer.save()

(2) save()的源码

断言的跳过不看,直接看 self.instance,发现如果self对象里面
有instance时,则调用update()方法
没有instance时,则调用create()方法
但是当我们点过去update()方法或者create()方法后
有一句话,create()` must be implemented
也就是说,这个update()以及create()方法,要我们继承后,去实现,不然就会报错

 def save(self, **kwargs):
    assert hasattr(self, '_errors'), (
        'You must call `.is_valid()` before calling `.save()`.'
    )

    assert not self.errors, (
        'You cannot call `.save()` on a serializer with invalid data.'
    )

    # Guard against incorrect use of `serializer.save(commit=False)`
    assert 'commit' not in kwargs, (
        "'commit' is not a valid keyword argument to the 'save()' method. "
        "If you need to access data before committing to the database then "
        "inspect 'serializer.validated_data' instead. "
        "You can also pass additional keyword arguments to 'save()' if you "
        "need to set extra attributes on the saved model instance. "
        "For example: 'serializer.save(owner=request.user)'.'"
    )

    assert not hasattr(self, '_data'), (
        "You cannot call `.save()` after accessing `serializer.data`."
        "If you need to access data before committing to the database then "
        "inspect 'serializer.validated_data' instead. "
    )

    validated_data = {**self.validated_data, **kwargs}
    # 自己写的序列化器的对象 self
    # instance 没传的话,create方法
    if self.instance is not None:
        self.instance = self.update(self.instance, validated_data)
        assert self.instance is not None, (
            '`update()` did not return an object instance.'
        )
    else:
        self.instance = self.create(validated_data)
        assert self.instance is not None, (
            '`create()` did not return an object instance.'
        )

    return self.instance

    def create(self, validated_data):
        raise NotImplementedError('`create()` must be implemented.')
    
    def update(self, instance, validated_data):
        raise NotImplementedError('`update()` must be implemented.')

(3) 实现create()方法

好处就是,解耦,将保存的逻辑解耦出去,

from django.http import HttpResponse
from django.shortcuts import render
from rest_framework.views import APIView
from sers.models import Book

from rest_framework import serializers
from rest_framework.response import Response

# 针对模型,设计序列化器
class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=32)
    price = serializers.IntegerField()
    date = serializers.DateField(source='pub_date')

    # 重写或者说是,实现create()方法
    def create(self, validated_data):
        new_book = Book.objects.create(**self.validated_data)
        return new_book


class BookView(APIView):

    # 查
    def get(self, request):
        # 获取所有的书籍
        book_list = Book.objects.all()
        # 构建序列化器对象    BookSerializers(instance=,data=,many=)
        # instance,是用来做序列化器的
        # data,是用来做反序列化器的
        # many, 序列化的是一个模型类对象还是多个模型类对象, True/Falseid
        serializer = BookSerializers(instance=book_list, many=True)
        return Response(serializer.data)

    # 增
    def post(self, request):
        # 获取参数
        data = request.data

        #  构建序列化器对象
        serializer = BookSerializers(data=data)

        # 校验数据
        # 校验原理:
        # 1.所有符合的数据都放在,serializer.validated_data
        # 2.不符合数据的都放在,serializer.errors
        if serializer.is_valid():   # 返回一个布尔值,所有字段都符合才返回True,反之,返回False
            # 数据校验通过,存入数据库中
            # new_book = Book.objects.create(**serializer.validated_data)

            serializer.save()

            return Response(serializer.data)
        else:
            # 数据校验失败
            return Response(serializer.errors)

四、序列化器,对资源进行增删改查(全部)查(一个)

具体看代码

from django.http import HttpResponse
from django.shortcuts import render
from rest_framework.views import APIView
from sers.models import Book

from rest_framework import serializers
from rest_framework.response import Response


# 针对模型,设计序列化器
class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=32)
    price = serializers.IntegerField()
    date = serializers.DateField(source='pub_date')

    # 重写或者说是,实现create()方法
    def create(self, validated_data):
        new_book = Book.objects.create(**self.validated_data)
        return new_book

    def update(self, instance, validated_data):
        Book.objects.filter(pk=instance.pk).update(**self.validated_data)
        update_book = Book.objects.get(pk=instance.pk)
        return update_book


class BookView(APIView):

    # 查所有
    def get(self, request):
        # 获取所有的书籍
        book_list = Book.objects.all()
        # 构建序列化器对象    BookSerializers(instance=,data=,many=)
        # instance,是用来做序列化器的
        # data,是用来做反序列化器的
        # many, 序列化的是一个模型类对象还是多个模型类对象, True/Falseid
        serializer = BookSerializers(instance=book_list, many=True)
        return Response(serializer.data)

    # 增加一个
    def post(self, request):
        # 获取参数
        data = request.data

        #  构建序列化器对象
        serializer = BookSerializers(data=data)

        # 校验数据
        # 校验原理:
        # 1.所有符合的数据都放在,serializer.validated_data
        # 2.不符合数据的都放在,serializer.errors
        if serializer.is_valid():  # 返回一个布尔值,所有字段都符合才返回True,反之,返回False
            # 数据校验通过,存入数据库中
            # new_book = Book.objects.create(**serializer.validated_data)

            serializer.save()

            return Response(serializer.data)
        else:
            # 数据校验失败
            return Response(serializer.errors)


class BookDetailsView(APIView):

    # 查一个
    def get(self, request, id):
        book = Book.objects.get(pk=id)
        serializer = BookSerializers(instance=book)
        return Response(serializer.data)

    def put(self, request, id):
        book = request.data
        update_book = Book.objects.get(pk=id)
        # 构建序列化器对象
        serializer = BookSerializers(instance=update_book, data=book)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)

    def delete(self, request, id):
        Book.objects.get(pk=id).delete()
        return Response()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还是那个同伟伟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值