返回顶部
首页 > 资讯 > 后端开发 > Python >drf序列化器serializer的具体使用
  • 763
分享到

drf序列化器serializer的具体使用

2024-04-02 19:04:59 763人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录一、序列化器-serializer二、序列化器的使用简单使用高级使用source**SerializerMethodField( ) **通用参数三、反序列化数据校验字段属性局部

一、序列化器-serializer

  • 序列化,序列化器会把模型对象转成字典,经过response以后变成JSON字符串
  • 反序列化:把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型
  • 反序列化:完成数据校验功能

二、序列化器的使用

序列化器的使用分为两个阶段:

  • 在客户端请求时,使用序列化器可以完成对数据的反序列化。
  • 服务器响应时,使用序列化器可以完成对数据的序列化。

简单使用

1、创建一个表模型


from Django.db import models

class Books(models.Model):
    title = models.CharField(verbose_name='书名', max_length=32)
    publish = models.CharField(verbose_name='出版社', max_length=32)
    price = models.DecimalField(verbose_name='价格', max_digits=5, decimal_places=2)

2、新建一个py文件,写一个序列化的类,继承Serializer

3、在类中写要序列化的字段,想序列化那个字段,就在类中写那个字段


from rest_framework import serializers

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField()

4、在视图类中使用,导入——》实例化得到序列化对象,把要序列化的对象传入

5、序列化的对象.data——》是一个字典

6、把字典返回,如果不使用rest_framework提供的Response,就得使用jsonResponse


from rest_framework.views import apiView
from rest_framework.request import Request
from app01.models import Books
from app01.ser import BooksSerializer

class BookView(APIView):
    def get(self, request, pk):
        # 响应信息
        response_msg = {'status': 200, 'message': '查询成功'}
        # 获取要序列化的对象
        book = Books.objects.filter(pk=pk).first()
        # 要序列化谁就把谁传到序列化类去
        book_ser = BooksSerializer(book)
        # book_ser.data————》序列化对象.data————》就是序列化后的字典
        # 将查询结果添加到响应信息内
        response_msg['data'] = book_ser.data
        return Response(response_msg)
    
 # urls.py
re_path(r'^book/(?P<pk>\d+)/', views.BookView.as_view()),

7、如果要被序列化的是包含多条数据的查询集queryset,可以通过添加many=True参数


from rest_framework.views import APIView
from rest_framework.response import Response
from app01.models import Books
from app01.ser import BooksSerializer


class BooksView(APIView):
    def get(self, request):
        # 响应信息
        response_msg = {'status': 200, 'message': '查询成功'}
        books = Books.objects.all()
        # 要序列化谁就把谁传到序列化类去
        book_ser = BooksSerializer(books, many=True)
        # book_ser.data————》序列化对象.data————》就是序列化后的字典
        # 将查询结果添加到响应信息内
        response_msg['data'] = book_ser.data
        return Response(response_msg)

# urls.py
re_path(r'^books/', views.BookView.as_view()),

高级使用

source

1、可以修改字段名字


class BooksSerializer(serializers.Serializer):
    xxx = serializers.CharField(source='title')  # 相当于——》xxx = Books.title
      
# 响应
{
    "status": 200,
    "message": "查询成功",
    "data": {
        "xxx": "魔道祖师"   ————》响应的字段名被修改了
    }
}

2、可以跨表查询


class BookSerializer(serializers.Serializer):
    publish_email = serializers.CharField(source='publish.email')
    # 相当于——》publish_email = Book.publish.email 连表查询publish表的email字段
    
    
# 响应
{
    "status": 200,
    "message": "查询成功",
    "data": {
        "publish_email": "modao@163.com"
    }
}

3、可以执行方法


# models.py
class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.IntegerField()
    pub_date = models.DateTimeField()
    publish = models.ForeignKey("Publish", on_delete=models.CASCADE, null=True)
    authors = models.ManyToManyField("Author")

    def func(self):
        return '666666'

    
# ser.py
class BookSerializer(serializers.Serializer):
    msg = serializers.CharField(source='func')
    # msg = Book.func  ——》调用Book类中的func()方法的返回值
    
    
# 响应
{
    "status": 200,
    "message": "查询成功",
    "data": {
        "msg": "666666"
    }
}

**SerializerMethodField( ) **

它需要有一个配套的方法,方法名叫做get_字段名,返回值就是要显示的东西


class BookSerializer(serializers.Serializer):
    authors = serializers.SerializerMethodField()

    def get_authors(self, instance):
        # instance ——》 Book对象
        authors = instance.authors.all()    # 取出所有作者
        author_list = []
        for author in authors:
            author_list.append({'name': author.name, 'age': author.age})
        return author_list

通用参数

read_only:(只读)表明该字段仅用于序列化输出,默认False,如果设置成True,响应中可以看到该字段,修改时,不需要传该字段

write_only:(只写)表明该字段仅用于反序列化输入,默认False,如果设置成True,响应中看不到该字段,修改时,该字段需要传


from rest_framework import serializers

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField(read_only = True)  # 响应中能看到改字段,修改不需要传值
    publish = serializers.CharField(write_only = True) # 响应中看不到改字段,修改需要传值
    price = serializers.DecimalField()

还有参数如下:

  • required  表明该字段在反序列化时必须输入,默认True
  • default   反序列化时使用的默认值
  • allow_null  表明该字段是否允许传入None,默认False
  • validators  该字段使用的验证器
  • error_messages 包含错误编号与错误信息的字典

三、反序列化数据校验

当使用序列化器对数据进行反序列化时,就需要对数据进行校验了,只有校验成功的数据才能被保存成模型类对象

将要校验的数据传入序列化器中并实例化:obj = BooksSerializer(data=request.data),调用is_valid()方法校验,校验成功返回True,失败返回False。

失败,可以通过序列化器对象的errors获取错误信息(字典)

成功,可以公共序列化对象的validated_data属性获取数据。

校验方法有:局部钩子,全局钩子,validators,和序列化类型和字段属性也是

字段属性

  • max_length  最大长度
  • min_lenght  最小长度
  • allow_blank  是否允许为空
  • trim_whitespace 是否截断空白字符
  • max_value  最小值
  • min_value  最大值

局部钩子

在序列化器类中创建局部钩子:validate_字段名,并且接收一个参数


# ser.py
class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    
    # 局部钩子对price字段校验
    def validate_price(self, data):
        if float(data) > 20:
            # 校验成功就通过
            return data
        else:
            # 校验失败就抛异常
            raise ValidationError('价格太低')

全局钩子

全局钩子:validate( ), 接收一个参数,

同时对多个字段进行比较验证


# ser.py
class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    
def validate(self, validate_data):
    title = validate_data.get('title')
    publish = validate_data.get('publish')
    if not title == publish:
        return validate_data
    else:
        raise ValidationError('书名和出版社不能一致')

validators

使用字段的validators=[func],来校验


# ser.py
# 校验函数
def check_price(data):
    if float(data) > 10:
        return data
    else:
        raise ValidationError('价格太低')

class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.CharField(validators=[check_price]) # 配置

四、序列化器操作数据

查询所有


# views.py
class BooksView(APIView):
    def get(self, request):
        # 响应信息
        response_msg = {'status': 200, 'message': '查询成功'}
        # 获取所有数据
        books = Books.objects.all()
        # 把数据谁传到序列化器中
        book_ser = BooksSerializer(instance=books, many=True) # 序列化多条需要加 many=True
        # book_ser.data————》序列化对象.data————》就是序列化后的字典
        # 将查询结果添加到响应信息内
        response_msg['data'] = book_ser.data
        return Response(response_msg)
    
# urls.py
path('books/', views.BooksView.as_view()),

查询单条


# views.py
class BookView(APIView):
    def get(self, request, pk):
        # 响应信息
        response_msg = {'status': 200, 'message': '查询成功'}
        # 获取要序列化的对象
        book = Books.objects.filter(pk=pk).first()
        # 要序列化谁就把谁传到序列化器中
        book_ser = BooksSerializer(instance=book)
        # book_ser.data————》序列化对象.data————》就是序列化后的字典
        # 将查询结果添加到响应信息内
        response_msg['data'] = book_ser.data
        return Response(response_msg)
    
# urls.py
re_path(r'^book/(?P<pk>\d+)/', views.BookView.as_view()),

新增数据

新增数据需要在序列化器中重写create( ) 方法:

注意没有传递instance实例,则调用save()方法的时候,create()被调用,相反,如果传递了instance实例,调用save()方法的时候,update()被调用。


# views.py
class BookView(APIView):
    def post(self, request):
        # 响应信息
        response_msg = {'status': 201, 'message': '增加成功'}
        # 修改才有instance,新增没有instance,只有data
        book_ser = BooksSerializer(data=request.data)

        # 校验字段
        if book_ser.is_valid():
            book_ser.save()  # 需要在序列化器中重写create()方法
            # 保存成功把原数据返回
            response_msg['data'] = book_ser.data
        else:
            response_msg['status'] = 202
            response_msg['message'] = '数据校验失败'
            response_msg['data'] = book_ser.error_messages
        return Response(response_msg)
    
    
# ser.py
class BooksSerializer(serializers.Serializer):
    title = serializers.CharField()
    publish = serializers.CharField()
    price = serializers.DecimalField(max_digits=5, decimal_places=2)

    # 重写create
    def create(self, validated_data):   # validated_data——>传入的新增数据
        instance = Books.objects.create(**validated_data)
        # instance——> 新增的字段对象,需要返回
        return instance
       
# urls.py
path('book/', views.BookView.as_view()),

修改数据

修改数据需要在序列化器中重写update( ) 方法:


# views.py
class BookView(APIView):
    def put(self, request, pk):
        # 响应信息
        response_msg = {'status': 200, 'message': '修改成功'}
        # 获取需要修改的字段对象
        book = Books.objects.filter(pk=pk).first()
        # 将字段对象和修改数据添加到序列化器中
        book_ser = BooksSerializer(instance=book, data=request.data)

        # 校验数据
        if book_ser.is_valid():
            book_ser.save()     # 需要在序列化器中重写update()方法
            response_msg['data'] = book_ser.data
        else:
            response_msg['status'] = 202
            response_msg['message'] = '数据校验失败'
            response_msg['data'] = book_ser.error_messages
        return Response(response_msg)
    
# urls.py
re_path('book/(?P<pk>\d+)', views.BookView.as_view()),

删除数据


# views.py
class BooksView(APIView):
    def delete(self, request, pk):
    # 响应信息
    response_msg = {'status': 200, 'message': '删除成功'}
    # 删除数据
    Books.objects.filter(pk=pk).delete()
    return Response(response_msg)
    
# urls.py
re_path('book/(?P<pk>\d+)', views.BooksView.as_view()),

五、模型类序列化器

DRF提供了ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类。

ModelSerializer与常规的Serializer相同,但是提供了:

  • 基于模型类自动生成一系列字段
  • 基于模型类自动为Serializer生成validators,比如unique_together
  • 包含默认的create( ) 和update( )。

实例:


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book        # 指明参照那个模型类
        fields = '__all__'  # 为模型类的那些字段生成

字段操作

1、可以使用fields来明确字段,__all__表示包含所以字段,具体那些字段->fields = ('title','price')

2、exclude表示排除那些字段,不能和fields一起写——>exclude = ('price',)

3、额外参数extra_kwargs,给字段添加额外的参数


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book        # 指明参照那个模型类
        fields = '__all__'  # 为模型类的那些字段生成
  
        # 类似于  title = serializers.CharField(read_only = True)
        extra_kwargs = {
            'title': {'read_only': True},
        }

六、源码分析many=True

当我们需要查询多条数据时就需要在实例化序列化器的时候传many=True


book_ser = BooksSerializer(instance=books, many=True) # 查询多条
book_one_ser = BooksSerializer(instance=book) # 查询单条

print(type(book_ser))
#<class 'rest_framework.serializers.ListSerializer'>

print(type(book_one_ser))
#<class 'app01.ser.BookModelSerializer'>

# 对象的生成-->先调用类的__new__方法,生成空对象,如果many=True,生成ListSerializer对象,反之生成Serializer对象

# 类的__new__方法控制对象的生成
def __new__(cls, *args, **kwargs):
    # 如果many=True,就会自动创建ListSerializer类
    if kwargs.pop('many', False):
        return cls.many_init(*args, **kwargs)
    return super().__new__(cls, *args, **kwargs)

到此这篇关于drf序列化器serializer的具体使用的文章就介绍到这了,更多相关drf序列化器serializer内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: drf序列化器serializer的具体使用

本文链接: https://lsjlt.com/news/129796.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • drf序列化器serializer的具体使用
    目录一、序列化器-serializer二、序列化器的使用简单使用高级使用source**SerializerMethodField( ) **通用参数三、反序列化数据校验字段属性局部...
    99+
    2024-04-02
  • Django 序列化的具体使用
    目录一、简介二、使用1.基本使用2.自定义序列化字段3.连表序列化以及深度控制4.序列化字段url一、简介 django rest framework 中的序列化组件,可以说是其核...
    99+
    2024-04-02
  • java自定义序列化的具体使用
    目录1.问题引出 2.解决办法 3.另外一种自定义序列化机制(介绍Externalizable) 1.问题引出 在某些情况下,我们可能不想对于一个对象的所有field进行序列化,例...
    99+
    2024-04-02
  • Web开发模式、API接口、restful规范、序列化和反序列化、drf安装和快速使用、路由转换器(复习)
    一 Web开发模式 1. 前后端混合开发模式 前后端混合开发模式是一种开发方式,将前端和后端的开发工作结合在一起,以加快项目的开发速度和提高协作效率。这种模式通常用于快速原型开发、小型项目或敏捷开发中。在前后端混合开发模式中,前端和后端开发...
    99+
    2023-08-30
    前端 restful 状态模式 django python pycharm windows
  • Golang中Json的序列化和反序列化的使用
    目录 JSON:创建格式:基本数据类型序列化:map序列化:切片序列化:反序列化为结构体:反序列化为map:反序列化为切片: JSON: JSON(JavaScr...
    99+
    2024-04-02
  • C++11新特性之列表初始化的具体使用
    目录统一的初始化方法列表初始化的一些使用细节初始化列表1、任何长度的初始化列表2、std::initialzer-list的使用细节列表初始化防止类型收窄在我们实际编程中,我们经常会...
    99+
    2024-04-02
  • Golang怎么使用gob实现结构体的序列化
    本文小编为大家详细介绍“Golang怎么使用gob实现结构体的序列化”,内容详细,步骤清晰,细节处理妥当,希望这篇“Golang怎么使用gob实现结构体的序列化”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Gol...
    99+
    2023-07-05
  • Python使用protobuf序列化和反序列化的实现
    protobuf介绍 protobuf是一种二进制的序列化格式,相对于json来说体积更小,传输更快。 安装protobuf 安装protobuf的目的主要用来将proto文件编译成python、c、Java可调...
    99+
    2022-06-02
    Python 序列化和反序列化
  • 如何使用Python中的序列化和反序列化
    如何使用Python中的序列化和反序列化,需要具体代码示例序列化和反序列化是在数据存储和传输过程中非常重要的概念。在Python中,我们可以使用pickle模块来实现序列化和反序列化操作。本文将详细介绍如何使用Python中的pickle模...
    99+
    2023-10-22
    Python 序列化 反序列化
  • java序列化与反序列化的使用方法汇总
    一、概念        java对象序列化的意思就是将对象的状态转化成字节流,以后可以通过这些值再生成相同状态的对象。对象...
    99+
    2024-04-02
  • Golang中Json的序列化和反序列化怎么使用
    这篇文章主要介绍“Golang中Json的序列化和反序列化怎么使用”,在日常操作中,相信很多人在Golang中Json的序列化和反序列化怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang中Js...
    99+
    2023-06-30
  • Java高性能序列化工具Kryo怎么使用
    本文小编为大家详细介绍“Java高性能序列化工具Kryo怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java高性能序列化工具Kryo怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。概述Kryo ...
    99+
    2023-07-02
  • Go 结构体序列化的实现
    目录更改JSON对象中的键在JSON对象中隐藏结构体字段附加内容结构体标签string指令本文,我们将回到之前写的showMovieHandler方法,并更新它以返回一个JSON响应...
    99+
    2024-04-02
  • 带指针的结构体序列化
    哈喽!大家好,很高兴又见面了,我是编程网的一名作者,今天由我给大家带来一篇《带指针的结构体序列化》,本文主要会讲到等等知识点,希望大家一起学习进步,也欢迎大家关注、点赞、收藏、转发! 下面就一起来看...
    99+
    2024-04-04
  • 浅析Go中序列化与反序列化的基本使用
    目录什么是序列化与反序列化序列化工作原理在Go中如何序列化一个对象如何格式化序列化后的数据如何给序列化后的xml加上属性如何将xml反序列化为一个对象什么是序列化与反序列化 这里引入...
    99+
    2023-05-16
    Go序列化 反序列化使用 Go序列化 反序列化 Go序列化 Go 反序列化
  • podman容器工具的具体使用
    目录podman简介Podman和Docker的主要区别是什么?podman安装使用配置镜像加速相关工具podman简介 Podman是一个开源项目,可在大多数Linux平台上使用并...
    99+
    2024-04-02
  • Golang使用gob实现结构体的序列化过程详解
    目录Gob简介单个对象序列化列表数据序列化简单编码示例编码在TCP连接中使用Golang有自己的序列化格式,称为gob。使用gob可以对结构进行编码和解码。你可以使用其他格式,如JS...
    99+
    2023-03-08
    Golang序列化结构体 Golang gob序列化
  • 小程序wx.getUserProfile接口的具体使用
    最近微信小程序对于审核小程序提出了带有wx.login、wx.getUserInfo接口的调整,并提出了一个新的接口供开发者调用 下图是对于新的接口的官方文档详情 点击前往官网查看更...
    99+
    2024-04-02
  • 怎么在python中使用序列化与反序列化
    这篇文章将为大家详细讲解有关怎么在python中使用序列化与反序列化,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。python有哪些常用库python常用的库:1.requesuts;2.s...
    99+
    2023-06-14
  • Redis可视化工具Redis Desktop Manager的具体使用
    项目中用到了redis,想查询redis中的数据,一直想找一个可视化工具,今天发现了Redis Desktop Manager,试用了一下,很好用。 1.下载 Redis Des...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作