DRF序列化器基本使用

DRF序列化器基本使用

  • 对用户提交的数据进行校验
  • 从数据库中取到数据进行序列化,转化为JSON格式返还给前端

1 序列化数据

1.1 Serializer
# models.py
from django.db import modelsclass Depart(models.Model):"""部门表"""title = models.CharField(verbose_name="标题", max_length=32)number = models.CharField(verbose_name="代号", max_length=16, default=1)
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from api import modelsclass DemoSerializer(serializers.Serializer):id = serializers.IntegerField()title = serializers.CharField()number = serializers.CharField()class DemoView(APIView):def get(self, request):# 1.数据库获取多条数据# queryset = models.Depart.objects.all()# ser = DemoSerializer(instance=queryset, many=True) 内部会循环queryset的每一个对象,再返回# 2.数据库获取单条数据instance = models.Depart.objects.filter(id=1).first()ser = DemoSerializer(instance=instance, many=False)print(type(ser.data), ser.data)return Response(ser.data)
1.2 ModelSerializer
from django.db import modelsclass Depart(models.Model):"""部门表"""title = models.CharField(verbose_name="标题", max_length=32)number = models.CharField(verbose_name="代号", max_length=16, default=1)
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from api import modelsclass DemoSerializer(serializers.ModelSerializer):class Meta:model = models.Depart# fields = "__all__"	# 所有字段# fields = ['id', 'title', 'number']	# 指定字段exclude = ["id"]	# 剔除某个字段class DemoView(APIView):def get(self, request):# 1.数据库获取多条数据# queryset = models.Depart.objects.all()# ser = InfoSerializer(instance=queryset, many=True)# 2.数据库获取单条数据instance = models.Depart.objects.filter(id=1).first()ser = InfoSerializer(instance=instance, many=False)print(type(ser.data), ser.data)return Response(ser.data)

很显然,如果要对数据表中的字段进行序列化,使用ModelModelSerializer是要比Serializer更简洁一些的。

1.3 自定义字段和参数

ModelModelSerializerSerializer中都可以自定义字段,并传入一些相关参数。

from django.db import modelsclass Depart(models.Model):"""部门表"""title = models.CharField(verbose_name="标题", max_length=32)number = models.CharField(verbose_name="代号", max_length=16, default=1)class UserInfo(models.Model):name = models.CharField(verbose_name="姓名", max_length=32)gender = models.SmallIntegerField(verbose_name="性别", choices=((1, "男"), (2, "女")))role = models.ForeignKey(verbose_name="角色", to="Role", on_delete=models.CASCADE)ctime = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from api import modelsclass InfoSerializer(serializers.ModelSerializer):gender = serializers.CharField(source="get_gender_display")role = serializers.CharField(source="role.title")ctime = serializers.DateTimeField(format="%Y-%m-%d")other_name = serializers.CharField(source="name")mine = serializers.SerializerMethodField()class Meta:model = models.UserInfofields = ['id', 'name', 'gender', "role", 'ctime', "other_name", "mine"]def get_mine(self, obj):return "x-x-{}".format(obj.name)class InfoView(APIView):def get(self, request):queryset = models.UserInfo.objects.all()ser = InfoSerializer(instance=queryset, many=True)print(type(ser.data), ser.data)return Response(ser.data)
1.4 序列化类嵌套

主要是ORM类中对应ForeignKeyManyToManyField的字段进行序列化。

  • 基于SerializerMethodField自定义方法对关联表数据进行序列化
  • 基于嵌套的序列化类实现
# models.py
from django.db import modelsclass Role(models.Model):title = models.CharField(verbose_name="标题", max_length=32)order = models.IntegerField(verbose_name="顺序")class Tag(models.Model):caption = models.CharField(verbose_name="名称", max_length=32)class UserInfo(models.Model):name = models.CharField(verbose_name="姓名", max_length=32)gender = models.SmallIntegerField(verbose_name="性别", choices=((1, "男"), (2, "女")))role = models.ForeignKey(verbose_name="角色", to="Role", on_delete=models.CASCADE)ctime = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)tags = models.ManyToManyField(verbose_name="标签", to="Tag")
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from api import modelsclass RoleSerializer(serializers.ModelSerializer):class Meta:model = models.Role# fields = "__all__"fields = ["id", 'title']class TagSerializer(serializers.ModelSerializer):class Meta:model = models.Tagfields = "__all__"class InfoSerializer(serializers.ModelSerializer):role = RoleSerializer()tags = TagSerializer(many=True)class Meta:model = models.UserInfofields = ['id', 'name', "role", "tags"]class InfoView(APIView):def get(self, request):queryset = models.UserInfo.objects.all()ser = InfoSerializer(instance=queryset, many=True)print(type(ser.data), ser.data)return Response(ser.data)
1.5 序列化类继承
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from api import modelsclass MySerializer(serializers.Serializer):more = serializers.SerializerMethodField()def get_more(self, obj):return "123"class InfoSerializer(serializers.ModelSerializer, MySerializer):class Meta:model = models.UserInfofields = ["id", "name", 'more']class InfoView(APIView):def get(self, request):instance = models.UserInfo.objects.all().first()ser = InfoSerializer(instance=instance, many=False)print(type(ser.data), ser.data)return Response(ser.data)

2 数据校验

对用户发来的请求数据进行校验 + 保存

GET请求	-> 获取数据(列表)
POST请求  -> 新增数据
PUT请求   -> 更新数据
2.1 内置校验
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializersclass InfoSerializer(serializers.Serializer):title = serializers.CharField(required=True, max_length=20, min_length=6)order = serializers.IntegerField(required=False, max_value=100, min_value=10)level = serializers.ChoiceField(choices=[("1", "高级"), (2, "中级")])class InfoView(APIView):def post(self, request):ser = InfoSerializer(data=request.data)if ser.is_valid():return Response(ser.validated_data)else:return Response(ser.errors)# def post(self, request):#     ser = InfoSerializer(data=request.data)#     ser.is_valid(raise_exception=True)	如果校验失败,则返回错误;校验成功,继续向后走(本质与上文一样)#     return Response(ser.validated_data)
2.2 正则校验
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from django.core.validators import RegexValidator, EmailValidatorclass InfoSerializer(serializers.Serializer):title = serializers.CharField(required=True, max_length=20, min_length=6)order = serializers.IntegerField(required=False, max_value=100, min_value=10)level = serializers.ChoiceField(choices=[("1", "高级"), (2, "中级")])# email = serializers.EmailField()email = serializers.CharField(validators=[EmailValidator(message="邮箱格式错误")])more = serializers.CharField(validators=[RegexValidator(r"\d+", message="格式错误")])code = serializers.CharField()class InfoView(APIView):def post(self, request):ser = InfoSerializer(data=request.data)if ser.is_valid():return Response(ser.validated_data)else:return Response(ser.errors)
2.3 钩子校验
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework import exceptionsclass InfoSerializer(serializers.Serializer):title = serializers.CharField(required=True, max_length=20, min_length=6)order = serializers.IntegerField(required=False, max_value=100, min_value=10)code = serializers.CharField()def validate_code(self, value):print(value)if len(value) > 6:raise exceptions.ValidationError("字段钩子校验失败")return value# 上面所有字段全部校验成功之后再执行validatedef validate(self, attrs):print("validate=", attrs)# api_settings.NON_FIELD_ERRORS_KEY		全局配置错误信息(遇到错误时non_field_errors替换为相应的字段)# raise exceptions.ValidationError("全局钩子校验失败")return attrsclass InfoView(APIView):def post(self, request):ser = InfoSerializer(data=request.data)if ser.is_valid():return Response(ser.validated_data)else:return Response(ser.errors)
2.4 ModelSerializer校验
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework import exceptions
from api import models
from django.core.validators import RegexValidatorclass RoleSerializer(serializers.ModelSerializer):more = serializers.CharField(required=True)class Meta:model = models.Rolefields = ["title", "order", "more"]extra_kwargs = {"title": {"validators": [RegexValidator(r"\d+", message="格式错误")]},"order": {"min_value": 5},}def validate_more(self, value):return valuedef validate(self, attrs):return attrsclass InfoView(APIView):def post(self, request):ser = RoleSerializer(data=request.data)if ser.is_valid():return Response(ser.validated_data)else:return Response(ser.errors)
2.5 校验+保存
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers
from rest_framework import exceptions
from api import models
from django.core.validators import RegexValidatorclass RoleSerializer(serializers.ModelSerializer):more = serializers.CharField(required=True)class Meta:model = models.Rolefields = ["title", "order", "more"]extra_kwargs = {"title": {"validators": [RegexValidator(r"\d+", message="格式错误")]},"order": {"min_value": 5},}def validate_more(self, value):return valuedef validate(self, attrs):return attrsclass InfoView(APIView):def post(self, request):ser = RoleSerializer(data=request.data)if ser.is_valid():ser.validated_data.pop("more")ser.save()  # ser.save(v1=123,v2=234)return Response(ser.validated_data)else:return Response(ser.errors)

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

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

相关文章

[前端] Bearer令牌

Bearer令牌是一种常用的认证方式,特别是在实现OAuth 2.0协议时。Bearer令牌本质上是一个安全字符串,可以是任意的字符序列,用以证明持有者(Bearer)有权访问特定的资源。其名称“Bearer”意味着任何持有该令牌的人都可以…

38-3 Web应用防火墙 - 安装配置WAF

首先需要安装Centos 7 虚拟机:Centos7超详细安装教程_centos7安装教程-CSDN博客 安装配置WAF 在桌面环境中,右键点击打开终端,首先执行以下步骤: 1)安装必要的工具: 输入命令: sudo su yum install -y wget epel-release 2)第二步,安装依赖工具,输入以下命令: y…

阿里云CentOS7 打开/关闭防火墙 开放端口

#查看防火墙状态# systemctl status firewalld #关闭防火墙# systemctl stop firewalld #打开防火墙# systemctl start firewalld #添加开放2375端口# firewall-cmd --add-port2375/tcp --permanent #重载入添加的端口# firewall-cmd --reload #查询2375端口是否开启成…

【嵌入式AI开发】轻量化卷积神经网络Mnasnet(神经架构搜索)详解

前言:谷歌轻量化卷积神经网络Mnasnet,介于MobileNet V2和V3之间。使用多目标优化的目标函数,兼顾速度和精度,其中速度用真实手机推断时间衡量。提出分层的神经网络架构搜索空间,将卷积神经网络分解为若干block,分别搜索各自的基本模块,保证层结构多样性。 CVPR2019论文…

深入理解网络原理1

文章目录 前言一、网络初识1.1 IP地址1.2 端口号1.3 协议1.4 五元组1.5 协议分层 二、TCP/IP五层协议三、封装和分用四、客户端vs服务端4.1 交互模式4.2 常见的客户端服务端模型4.3 TCP和UDP差别 前言 随着时代的发展,越来越需要计算机之间互相通信,共享…

大模型咨询培训叶梓老师:数千大模型,1张GPU搞定——UC Berkeley提出全新微调方法S-LoRA

在大语言模型(LLM)的部署中,通常采用“预训练-微调”范式。为了适应多样化的任务,参数高效的微调方法如低秩适应(LoRA)被广泛使用。然而,如何高效地服务这些微调变体仍然是一个未探索的问题。S-…

VBA技术资料MF147:从Excel运行PowerPoint演示文稿

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…

redis ZRANGE 使用最详细文档

环境: redis_version:7.2.2 本文参考 redis 官方文档1 语法 ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count] [WITHSCORES]参数含义key是有序集合的键名start stop在不同语境下,可用值不一样BYSCORE | BYLEX按照分数查询 | 相…

OceanBase 分布式数据库【信创/国产化】- OceanBase 数据库的发展历程

本心、输入输出、结果 文章目录 OceanBase 分布式数据库【信创/国产化】- OceanBase 数据库的发展历程前言OceanBase 数据更新架构OceanBase 数据库的发展历程OceanBase 分布式数据库【信创/国产化】- OceanBase 数据库的发展历程 编辑 | 简简单单 Online zuozuo 地址 | https:…

React 15~18每个阶段更新了什么

文章目录 React 15React 16React 17 试验性并发模式React 18 React 15 React.createClass (弃用) class 组件 函数组件(无状态、纯UI组件) 堆栈diff(同步更新state1->state2->state3…、每个更新过程不可中断&a…

【SQL每日一练】统计复旦用户8月练题情况

文章目录 题目一、分析二、题解1.使用case...when..then2.使用if 题目 现在运营想要了解复旦大学的每个用户在8月份练习的总题目数和回答正确的题目数情况,请取出相应明细数据,对于在8月份没有练习过的用户,答题数结果返回0. 示例代码&am…

13、Flink 的 Operator State 详解

1.算子状态 (Operator State) 算子状态(或者非 keyed 状态)是绑定到一个并行算子实例的状态,Kafka consumer 每个并行实例维护了 topic partitions 和偏移量的 map 作为它的算子状态。 当并行度改变的时候,算子状态支持将状态重…

Excel 批量获取sheet页名称,并创建超链接指向对应sheet页

参考资料 用GET.WORKBOOK函数实现excel批量生成带超链接目录且自动更新 目录 一. 需求二. 名称管理器 → 自定义获取sheet页名称函数三. 配合Index函数,获取所有的sheet页名称四. 添加超链接,指向对应的sheet页 一. 需求 ⏹有如下Excel表,需…

Java 正则表达式代码演示

正则表达式(Regular Expressions)是一种用于描述字符串匹配模式的强大工具。在 Java 中,可以使用 java.util.regex 包来处理正则表达式。 文章目录 一、基本用法二、高级用法 一、基本用法 导入正则表达式类: import java.util.regex.Patte…

Easy TCP Analysis上线案例库功能,为用户提供一个TCP抓包分析案例分享学习的平台

​案例库,提供给用户相互分享TCP抓包故障排查案例或是经典学习案例的功能,任何用户都可从案例库查看其它用户分享的案例,每个用户也都可以上传自己的案例,经过平台审核去重即可展示在案例库。 对于学习,最典型的三次握…

webscoket+webrtc实现语音通话

1.项目方案 前端采用webrtc创建音频上下文,后创建音频源输入和音频处理器,连接音频输入与处理器,处理器再连接到音频输出(扬声器),再通过事件获取音频数据,把音频数据转换成字节数据通过webscok…

【Docker学习】docker start深入研究

docker start也是很简单的命令。但因为有了几个选项,又变得复杂,而且... 命令: docker container start 描述: 启动一个或多个已停止的容器。 用法: docker container start [OPTIONS] CONTAINER [CONTAINER...] 别名&…

【网络编程】网络基础

TCP/IP五层模型 物理层:负责光/电信号的传递方式. 比如现在以太网通用的网线(双绞线)、早期以太网采用的的同轴电缆(现在主要用于有线电视)、光纤,现在的 WIFI无线网使用电磁波等都属于物理层的概念。物理层…

搭建AI大模型步骤

搭建AI大模型需要以下步骤: 数据收集和预处理:收集大量的训练数据,并进行清洗、标注和预处理,使其适合模型训练。 模型选择:根据具体的任务需求,选择适合的深度学习模型,如卷积神经网络&#x…

QtConcurrent::run操作界面ui的注意事项

先说结论:QtConcurrent::run启动的耗时处理函数,不允许处理ui界面对象,如控件,如进度条等等! QtConcurrent::run非常好用,胜过QThead的两种方式(run和moveToThread),例如…