Backend - DRF 序列化(django-rest-framework)

目录

一、restful 、django-rest-framework 、swagger 三者的关系

(一)restful API(REST API)

1. rest

2. restful

3. api

4. restfulAPI

(二)django-rest-framework(简称DRF)

(三)swagger

二、DRF 基础配置

(一)安装依赖

(二)配置环境

三、自定义序列化器(定义序列化类,serializers)

(一)Django 序列化 & DRF 序列化器

1. Django 序列化

(1)序列化

(2)反序列化

2. DRF 序列化器

(二)序列化类

(三)常用字段

1. 序列化器的常用字段

2. 自定义字段类型

3. 字段的many参数

4. 字段的多关系子序列化 

(1)source参数的使用

① 重命名字段

② 跨表

③ 执行方法

(2)SerializerMethodField的使用

5. fields的必要性

6. exclude

7. validate_字段名

(四) 创建序列化器(定义序列化类)

1. 一般写法

2. 公共字段

四、使用序列化器(实例化)

(一)构造序列化对象

1. data

2. instance

(二)实例化后的类属性

1. data 属性

2. 实际应用

(1)单个数据模型

(2)多个数据模型

(三)实例化后的类方法

1. is_valid( ) 方法

(1)作用

(2)参数raise_exception

(3)配合validate_字段

2. save() 方法

3. 两者举例

(1)简单举例

(2)完整应用

(四)运行查看

1. 设置路由(urls)

2. 运行情况

五、问题解决

1. ValidationError({'non_field_errors': [ErrorDetail(string='Expected a list of items but got type "dict".', code='not_a_list')]})

2. "The field 'XXX' was declared on serializer SerializerRecipeBodySave, but has not been included in the 'fields' option."


一、restful 、django-rest-framework 、swagger 三者的关系

(一)restful API(REST API)

1. rest

        架构的设计风格,即架构规范(该篇文章主要针对接口的请求方式)。

2. restful

        符合rest原则的开发理念(设计标准)。

3. api

        通讯接口。

4. restfulAPI

        使用REST风格理念的接口(每一种请求API,对应后端的一种数据库操作)。

(二)django-rest-framework(简称DRF)

        是针对Django,生成restfulAPI的框架(序列化)。

        即,给Django提供了跨平台跨语言的Web API框架。

        需安装依赖 djangorestframework,settings.py的INSTALLED_APPS引入rest_framework。

(三)swagger

        针对django-rest-framework(DRF),遵循rest风格理念(restful),生成接口开发文档的工具(UI 界面,可测试、也方便前后端对接)。

        需安装依赖 drf-yasg,settings配置INSTALLED_APPS引入drf_yasg。

swagger的应用,可参考另一篇文章:Backend - Django Swagger-CSDN博客

二、DRF 基础配置

(一)安装依赖

pip install djangorestframework==3.14.0

(二)配置环境

    # settings.py文件中INSTALLED_APPS = [...'rest_framework',...]

三、自定义序列化器(定义序列化类,serializers)

主要针对Serializers.py 和Models.py。

(一)Django 序列化 & DRF 序列化器

1. Django 序列化

针对DRF的序列化器的应用来讲:

(1)序列化

        序列器将orm模型或queryset物件转换成字典,再由response把字典转换成json的过程。

        即,后端传数据给前端时,将“查询集QuerySet格式”,最终序列化转为“json格式”。

(2)反序列化

        序列化器将request获取的json数据转化为python对象。

        即,前端将数据传给后端时,将json数据,最终反序列化为python对象。

2. DRF 序列化器

        虽然,Django有自带的序列化类(serializers类),但DRF提供的序列化器更实用。

(二)序列化类

        序列化器的序列化类有3种:

        Serializer、ListSerializer、ModelSerializer(最常用的)

(三)常用字段

1. 序列化器的常用字段

        CharField,IntegerField,DateField、BooleanField

2. 自定义字段类型

# 例如自定义Combobox
# 自定义复选框字段类型
class Combobox(serializers.Serializer):bookname = serializers.CharField()bookid = serializers.IntegerField()
# 使用复选框字段
class SerializerAuthor(serializers.Serializer):age = serializers.BooleanField()name = serializers.CharField()books = Combobox(many=False)

3. 字段的many参数

        序列化单个对象,默认参数many=False

        序列化多个对象,指定参数many=True

4. 字段的多关系子序列化 

(1)source参数的使用
① 重命名字段

        自定义返回给前端的字段名。

② 跨表

        获取外键表的字段。

③ 执行方法

        执行model模型类内的自定义方法。

# models.py
class BookType(models.Model):bid = models.AutoField(primary_key=True)name = models.CharField(max_length=32)color = models.CharField(max_length=32)fontsize = models.CharField(max_length=32)fontcolor = models.CharField(max_length=32)class PublishPlace(models.Model):nid = models.AutoField(primary_key=True)name = models.CharField(max_length=32)status =  models.BooleanField(default=True, db_index=True)city = models.CharField(max_length=32)email = models.CharField(max_length=32)class Author(models.Model):aid = models.AutoField(primary_key=True)name = models.CharField(max_length=32)age = models.IntegerField(default=10)sex = models.CharField(max_length=32)birthday = models.DateField()class Book(models.Model):bid = models.AutoField(primary_key=True)name = models.CharField(max_length=32)price = models.DecimalField(max_digits=5, decimal_places=2)booktype =  models.ForeignKey(to='BookType', to_field='bid', on_delete=models.CASCADE)publish = models.ForeignKey(to='PublishPlace', to_field='pid', on_delete=models.CASCADE)authors = models.ManyToManyField(to='Author')def __str__(self):return self.name# 取出该书的出版社def getpublishdata(self):return {'name': self.publish.name, 'city': self.publish.city, 'email': self.publish.email}# 取出该书的所有作者def all_author(self):return [{'id': author.aid, 'name': author.name, 'age': author.age} for author in self.authors.all()]
# serializers.py 
from rest_framework import serializers
from myAPP import model # 引入model.py
class AuthorSerializer(serializers.ModelSerializer):class Meta:model = Authorfields = "__all__"class SerializerBook(serializers.ModelSerializer):authors = AuthorSerializer(many=True)book_price = serializers.CharField(source='price') # price是数据库字段,book_price 是自命名的。book_type = serializers.CharField(source='booktype.name') # booktype是关联“书籍类型表”的外键字段。name是“书籍类型表”的字段。publish2 = serializers.DictField(source="getpublishdata") # 字典形式(执行模型类的方法)class Meta:model = model.Bookfields = [ 'name', 'publish', 'authors', 'Publish2', 'book_price','book_type'] # fields是设置最后返回的数据有哪些。book_price和book_type、Publish2 是上方自定义的字段名。 name、Publish、authors是数据库原本的字段名。
(2)SerializerMethodField的使用

        需要搭配 get_XXX( ) 方法。

        可自定义返回给前端的字段值格式。

        一般用于跨表查询。

# serializers.py
class SerializerBook(serializers.ModelSerializer):publish = serializers.SerializerMethodField() #设置序列化,才能用下面的get__XXX()方法。booktype = serializers.SerializerMethodField() class Meta:model = model.Bookfields = ['publish']  def get_publish(self, obj): # 自定义返回的数据格式return {'label': obj.city, 'value': obj.email} # city和email都是publish字段关联到的外表publishplace表的字段def get_booktype(self, obj):booktypes=obj.booktypes.all()  # 全部书籍样式b_list=list()for booktype in booktypes:b_list.append({'name':booktype.color,'age':booktype.fontsize})return b_list

5. fields的必要性

        自定义的字段、前端展示的字段,都需要在fields中填写。

6. exclude

        排除不需要显示的字段。

        注意:fields和exclude不能共存。

7. validate_字段名

        写在序列化器中(serializers.py中)。

        需要搭配实例化后的is_valid()方法(views.py中)。实例化序列化器在后面的模块中会讲。

class BookInfoSerializer(serializers.Serializer):price = serializers.BooleanField()name = serializers.CharField()class Meta:model = model.Bookfields = [ 'name', 'price','booktype']# ① 验证单个字段def validate_booktype(self, value):if '教育' not in value:raise serializers.ValidationError("该书籍不属于教育")return value
# ② 验证多个字段def validate(self, vals):price = vals['price'] booktype = vals['booktype']if  booktype =='教育' and price > 100  raise serializers.ValidationError("该教育书籍价格大于100")return value

(四) 创建序列化器(定义序列化类)

上述自定义序列化器中的一些相关实例,也有讲创建序列化器。

1. 一般写法

# 在myBook项目下新建book_serializer.py文档
from book_models import Book, Author
from rest_framework import serializers
class BookSerializer(serializers.ModelSerializer):class Meta:model = Book  # model名fields = '__all__'

2. 公共字段

# 在myBook项目下新建book_serializer.py文档
from book_models import Book, Author
from rest_framework import serializers# 不同的序列化,有共同字段
class BaseData(serializers.ModelSerializer):decription = serializers.CharField()class BookSerializer(BaseData):class Meta:model = Book  # model名fields = ['name', 'card', 'place', 'author', 'decription']class AuthorSerializer(BaseData):class Meta:model = Author  # model名fields = ['name', 'sex', 'age', 'place', 'decription']  

四、使用序列化器(实例化)

主要针对views.py。

(一)构造序列化对象

Serializer(instance=None, data=empty, **kwarg)  # 构造方法,初始化

其中,可传入 instance, data 等参数。

1. data

        是需要验证的资料,预设为empty。

2. instance

        格式:是针对某条queryset数据,预设为None。

        作用:

               实例化serializer(创建序列化对象)时,根据是否传入instance参数,判断执行update还是create。

                即,若传入的instance有值时,则instance.save调用update方法;

                反之,若传入的instance为None(或没有传instance)时,则instance.save调用create方法。

(二)实例化后的类属性

1. data 属性

        获取序列化后的数据。

2. 实际应用

(1)单个数据模型

# 在myBook项目下新建views_book.py文档
from rest_framework.generics import GenericAPIView
from django.http import JsonResponse
from django.db import transaction
from book_models import Book
from book_serializers import BookSerializer class BookView(GenericAPIView):def get(self, request, *args, **krgs):books_qst = Book.objects.get(id=1)  # 获取单笔数据book_seri = BookSerializer(books_qst, many=True)  # 数据转换,即数据序列化res =  book_seri.data  # 获取数据  {'id': 1, 'bookname': '数据结构', 'author': '萝卜干'}return JsonResponse(res)
(2)多个数据模型
# 在myBook项目下新建views_book.py文档
from rest_framework.generics import GenericAPIView
from django.http import JsonResponse
from django.db import transaction
from book_models import Book
from book_serializers import BookSerializer class BookView(GenericAPIView):def get(self, request, *args, **krgs):books_qst = Book.objects.all()  # 查询数据库,获取多笔数据book_seri = BookSerializer(books_qst, many=True)  # many=True,表示序列化多条数据res =  book_seri.data  # 获取数据 [('id', 1), ('bookname', '数据结构'),  ('author', '萝卜干')]return JsonResponse(res, safe=False) # 结果是列表,则需声明safe=False

(三)实例化后的类方法

1. is_valid( ) 方法

(1)作用

        验证newdata是否符合数据库数据规范。

(2)参数raise_exception

        raise_exception=True # 若验证时出现异常,会接收到此异常,向前端返回HTTP 400 响应。

(3)配合validate_字段

        在上述自定义序列化器的模块中,有讲解如何使用。

2. save() 方法

        保存当前数据。

3. 两者举例

(1)简单举例
bookins = models.Book.objects.first()
myserializer = BookSerializer(instance=bookins, data=newdata, partial=True)
myserializer.is_valid(raise_exception=True)
myserializer.save()
(2)完整应用
# 在myBook项目下新建views_book.py文档
from rest_framework.generics import GenericAPIView
from django.http import JsonResponse
from django.db import transaction
from book_models import Book
from book_serializers import BookSerializer class BookView(GenericAPIView):def post(self, request, *args, **krgs):book_data = request.datatry:serializer =BookSerializer(data=book_data)  # 更改数据库serializer.is_valid(raise_exception=True)  # 检查是否合格with transaction.atomic(): serializer.save()res = serializer.data # 获取序列化后的数据except Exception as e:res = {'error': str(e)}return JsonResponse(res)

(四)运行查看

1. 设置路由(urls)

        展示序列化数据的整体流程,涉及models、serializers、views、urls 模块。

# 在myPro项目下新建urls.py文档
from django.urls import path, re_path  # url规则
from myBook import views_book as book_viewurlpatterns = [...path('book/', book_view.BookView.as_view()),
] 

2. 运行情况

        浏览器输入链接,回车。

        链接:http://127.0.0.1:8080/myApp/book

        展示界面如下:

五、问题解决

1. ValidationError({'non_field_errors': [ErrorDetail(string='Expected a list of items but got type "dict".', code='not_a_list')]})

原因:在使用序列化时,many设置了为True。表示存入多笔,但实际若只存单笔,则会报错。

解决:many设置为False,或删除该属性。

2. "The field 'XXX' was declared on serializer SerializerRecipeBodySave, but has not been included in the 'fields' option."

原因:字段 XXX 已在序列化程序上声明,但尚未包含在fields“字段”选项中。

解决:在 fields = (  ) 中加上该字段。


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/821795.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Web3D智慧医院平台(HTML5+Threejs)

智慧医院的建设将借助物联网、云计算、大数据、数字孪生等技术,以轻量化渲染、极简架构、三维可视化“一张屏”的形式,让医院各大子系统管理既独立又链接,数据相互融合及联动。 建设医院物联网应用的目标对象(人、物)都…

7 pytorch DataLoader, TensorDataset批数据训练方法

前言 本文主要介绍pytorch里面批数据的处理方法,以及这个算法的效果是什么样的。具体就是要弄明白这个批数据选取的算法是在干什么,不会涉及到网络的训练。 from torch.utils.data import DataLoader, TensorDataset主要实现就是上面的数据集和数据载入…

pdf做批注编辑工具 最新pdf reader pro3.3.1.0激活版

PDF Reader Pro是一款功能强大的PDF阅读和编辑工具。它提供了多种工具和功能,帮助用户对PDF文档进行浏览、注释、编辑、转换和签名等操作。以下是PDF Reader Pro的一些主要特色: 最新pdf reader pro3.3.1.0激活版下载 多种查看模式:PDF Reade…

STM32 PB3 PB4 无法作为 GPIO 使用解决办法

如下所示,PA13 PA14 PB3 PB4 PB5, 默认是JTAG SWD的 PIN, 需要引脚ReMap 才能作为GPIO 使用。 HAL库解决办法 // __HAL_AFIO_REMAP_SWJ_ENABLE(); //Full SWJ (JTAG-DP SW-DP):// __HAL_AFIO_REMAP_SWJ_NONJTRST(); //Full SWJ (JTAG-DP SW-DP) but without NJTR…

【代理模式】静态代理-简单例子

在Java中,静态代理是一种设计模式,它涉及到为一个对象提供一个代理以控制对这个对象的访问。静态代理在编译时就已经确定,代理类和被代理类会实现相同的接口或者是代理类继承被代理类。客户端通过代理类来访问(调用)被…

认识异常(1)

❤️❤️前言~🥳🎉🎉🎉 hellohello~,大家好💕💕,这里是E绵绵呀✋✋ ,如果觉得这篇文章还不错的话还请点赞❤️❤️收藏💞 💞 关注💥&a…

计算机网络:MAC地址 IP地址 ARP协议

计算机网络:MAC地址 & IP地址 & ARP协议 MAC地址IP地址ARP协议 MAC地址 如果两台主机通过一条链路通信,它们不需要使用地址就可以通信,因为连接在信道上的主机只有他们两个。换句话说,使用点对点信道的数据链路层不需要使…

开源 Ruo-Yi 项目引入 Mybatis-Plus:3.5.3 报错ClassNotFoundException:

开源 Ruo-Yi 项目引入 Mybatis-Plus:3.5.3 报错ClassNotFoundException: Caused by: java.lang.ClassNotFoundException: com.baomidou.mybatisplus.extension.plugins.MybatisPlusInter1 分析问题 控制台报错说明我们引入的 mybatis-plus 的依赖里找不到com.baom…

数字化转型-工具变量数据集

01、数据介绍 数字化转型是指企业或个人利用数字技术,如大数据、云计算、人工智能等,对其业务流程、运营模式、决策方式等进行全面、深入的变革,以提高效率、降低成本、提升质量、增强竞争力。在这个过程中,工具变量扮演着至关重…

JVM虚拟机(九)如何开启 GC 日志

目录 一、引言二、开启 GC 日志三、解析 GC 日志四、优化建议 一、引言 在 Java 应用程序的运行过程中,垃圾收集(Garbage Collection,简称 GC)是一个非常重要的环节。GC 负责自动管理内存,回收不再使用的对象所占用的…

zabbix 自动发现与自动注册 部署 zabbix 代理服务器

zabbix 自动发现(对于 agent2 是被动模式) zabbix server 主动的去发现所有的客户端,然后将客户端的信息登记在服务端上。 缺点是如果定义的网段中的主机数量多,zabbix server 登记耗时较久,且压力会较大。1.确保客户端…

一次配置Docker环境的完整记录

一次配置Docker环境的完整记录 Docker环境搭建报错与解决报错一报错二报错三 Docker环境搭建 本节介绍了一次配置docker环境的完整记录: 编写Dockerfile文件: FROM pytorch/pytorch:1.10.0-cuda11.3-cudnn8-develRUN rm /etc/apt/sources.list.d/cuda.l…

mfc 带有复选框的ListBox

mfc 带有复选框的 ListBox 效果: 添加 ListBox 控件 从工具箱拖拽 ListBox 控件到窗口上,并设置属性: 包含字符串:true所有者描述:Fixed 给ListBox添加控制变量 添加完后,将m_list_box的类型使用CC…

Qt+vstudio2022的报错信息积累

从今天开始记录一下平常开发工作中的报错记录,后续有错误动态补充! 报错信息:【MSB8041】此项目需要 MFC 库。从 Visual Studio 安装程序(单个组件选项卡)为正在使用的任何工具集和体系结构安装它们。 解决: 背景:换…

uniapp--登录和注册页面-- login

目录 1.效果展示 2.源代码展示 测试登录 login.js 测试请求 request.js 测试首页index.js 1.效果展示 2.源代码展示 <template><view><f-navbar title"登录" navbarType"4"></f-navbar><view class"tips"><…

图数据库Neo4J入门——Neo4J下载安装+Cypher基本操作+《西游记》人物关系图实例

这里写目录标题 一、效果图二、环境准备三、数据库设计3.1 人物节点设计3.2 关系设计 四、操作步骤4.1 下载、安装、启动Neo4J服务4.1.1 配置Neo4J环境变量4.1.2 启动Neo4J服务器4.1.3 启动Ne04J客户端 4.2 创建节点4.3 创建关系&#xff08;从已有节点创建关系&#xff09;4.4…

PhpStorm2024安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 PhpStorm是由JetBrains公司开发的一款商业的PHP集成开发环境&#xff08;IDE&#xff09;&#xff0c;深受全球开发人员的喜爱。它旨在提高开发效率&#xff0c;通过深刻理解用户的编码习惯&#xff0c;提供智能代码补全、快速导…

Java面试八股文(JVM篇)(❤❤)

Java面试八股文_JVM篇 1、知识点汇总2、知识点详解&#xff1a;3、说说类加载与卸载11、说说Java对象创建过程12、知道类的生命周期吗&#xff1f;14、如何判断对象可以被回收&#xff1f;17、调优命令有哪些&#xff1f;18、常见调优工具有哪些20、你知道哪些JVM性能调优参数&…

vue的就地更新与v-for的key属性

vue的就地更新 Vue中的就地更新到底是怎么回事&#xff0c;为什么会存在就地更新的现象&#xff1f; 注意下面的例子&#xff0c;使用v-for指令时&#xff0c;没有绑定key值&#xff0c;才有就地更新的现象&#xff0c;因为Vue默认按照就地更新的策略来更新v-for渲染的元素列表…

CTFHUB-技能树-Web前置技能-文件上传(前端验证—MIME绕过、00截断、00截断-双写后缀)

CTFHUB-技能树-Web前置技能-文件上传&#xff08;前端验证—MIME绕过、00截断、00截断-双写后缀&#xff09; 文章目录 CTFHUB-技能树-Web前置技能-文件上传&#xff08;前端验证—MIME绕过、00截断、00截断-双写后缀&#xff09;前端验证—MIME绕过有关MIMEMIME的作用 解题时有…