Django(45)drf序列化类的使用(Serializer)
前言
上一篇文章我们讲述了序列化,这篇就带大家一起来实现以下序列化
Serializer
我们使用序列化类Serializer,我们来看下源码结构,这里推荐使用pycharm左边导航栏的Structure,可以清晰的看到一个文件的结构,如下图

我们会发现Serializer继承自BaseSerializer和SerializerMetaclass,但是Serializer类中又没有create方法和update方法,所以我们使用的时候必须自己手动定义这2个方法
准备工作
1.新建一个项目drf_demo,在项目中新建一个appdrf_app,在app中新建一个文件urls.py,项目结构如下

2.在models.py文件中写入如下代码
class Student(models.Model):
SEX_CHOICES = (
(1,'男'),
(2, '女')
)
name = models.CharField(max_length=20, verbose_name='姓名')
age = models.IntegerField(null=True, blank=True, verbose_name='年龄')
sex = models.IntegerField(choices=SEX_CHOICES, default=1, verbose_name='性别')
class Meta:
db_table = "student"
3.在drf_demo.urls.py和drf_app.urls.py中分别写入如下代码
# drf_demo.urls.py
urlpatterns = [
path('drf/', include('drf_app.urls')),
]
# drf_app.urls.py
app_name = "drf_app"
urlpatterns = [
path('student/', views.student),
]
4.在settings.py文件的MIDDLEWARE中注释掉django.middleware.csrf.CsrfViewMiddleware,并在INSTALLED_APPS中加入2个app
'rest_framework',
'drf_app'
5.在命令行输入以下命令,将orm对象映射到数据库
python manage makemigrations
python manage migrate
6.写序列化类一般我们都在app项目中新建serializers.py文件,接下来可以正式编写序列化类了
序列化类编写
# Serializer的构造函数的参数:
# 1. instance:需要传递一个orm对象,或者是一个queryset对象,用来将orm转成json
# 2. data:把需要验证的数据传递给data,用来验证这些数据是不是符合要求
# 3. many:如果instance是一个queryset对象,那么就需要设置为True,否则为False
class StudentSerializer(serializers.Serializer):
# 序列化提供给前台的字段个数由后台决定,可以少提供
# 但是提供的数据库对应的字段,名字一定要与数据库字段相同
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(required=True, max_length=200)
sex = serializers.IntegerField(required=True)
age = serializers.IntegerField(required=True)
def create(self, validated_data):
"""
根据提供的验证过的数据创建并返回一个新的`Student`实例
"""
return Student.objects.create(**validated_data)
def update(self, instance, validated_data):
"""
根据提供的验证过的数据更新和返回一个已经存在的`Student`实例。
"""
instance.name = validated_data.get('name', instance.name)
instance.age = validated_data.get('name', instance.age)
instance.sex = validated_data.get('name', instance.sex)
instance.save()
return instance
# 局部钩子 validate_要校验的字段名(self, 当前要校验字段的值)
def validate_name(self, value):
if 'j' in value.lower():
raise exceptions.ValidationError("名字非法")
return value
def validate_sex(self, value):
if not isinstance(value, int):
raise exceptions.ValidationError("只能输入int类型")
if value != 1 and value != 2 :
raise exceptions.ValidationError("只能输入男和女")
return value
# 全局钩子 validate(self, 系统与局部钩子校验通过的所有数据)
def validate(self, attrs):
age = attrs.get('age')
sex = attrs.get('sex')
if age < 22 and sex == 1:
raise exceptions.ValidationError({"age&sex": "男的必须22周岁以上才能结婚"})
return attrs
我们上面代码首先定义了序列化的字段,字段中的参数都继承自Field类,参数如下
def __init__(self, read_only=False, write_only=False,
required=None, default=empty, initial=empty, source=None,
label=None, help_text=None, style=None,
error_messages=None, validators=None, allow_null=False):
- read_only:当为
True时表示这个字段只能读,只有在返回数据的时候会使用。 - write_only:当为
True时表示这个字段只能写,只有在新增数据或者更新数据的时候会用到。比如我们的账号密码,只允许用户提交,后端是不返回密码给前台的 - required:当为
True时表示这个字段必填,不填状态码会返回400 - default:默认值,没什么好说的
- allow_null:当为
True时,允许该字段的值为空
之后我们又定义了局部钩子,校验特殊的字段,比如需求规定,用户的性别只能输入男和女,此时你就可以定义一个钩子,当然drf自动帮我们做了一些校验,比如需要的字段是int类型,你输入string类型,会自动触发系统的error,不需要我们额外定义,后面我们会进行测试
接下来我们又定义了一个全局的钩子,意思就是针对整个数据进行校验,最适合的场景比如密码重复输入,一般我们注册的时候,需要输入2次密码,第二次用来确认,这个场景就适合用全局钩子
编写完serializers后,我们最后一步,编写视图函数,如下:
def student(request):
# 获取所有的学生
if request.method == "GET":
# 创建一个queryset对象
stu = Student.objects.all()
# 将对象序列化为dict
stu_data = StudentSerializer(instance=stu, many=True).data
return JsonResponse(status=200, data=stu_data, safe=False)
elif request.method == "POST":
data = JSONParser().parse(request)
serializer = StudentSerializer(data=data)
# 校验字段是否符合规范
if serializer.is_valid():
# 符合则保存到数据库
serializer.save()
return JsonResponse(data=serializer.data, status=200)
return JsonResponse(serializer.errors, status=400)
测试
测试分为GET请求和POST请求
GET请求
我们打开接口测试工具postman或者apifox,这里以apifox为例,输入127.0.0.1:8000/drf/student/,得到了以下结果
[
{
"id": 1,
"name": "jkc",
"sex": 1,
"age": 18
},
{
"id": 2,
"name": "mary",
"sex": 2,
"age": 20
}
]
说明序列化成功,成功地将数据库的数据通过json的格式返回给了前台
POST请求
同样打开接口工具,输入127.0.0.1:8000/drf/student/,在body中选择json格式,输入如下数据
{
"name": "aaaa",
"sex": 2,
"age": 18
}
运行结果如下:
{
"id": 13,
"name": "aaaa",
"sex": 2,
"age": 18
}
说明我们反序列化也成功了,小伙伴们自己实践时可以查看数据库,会多了一条这样的数据
接下来我们是否能触发钩子函数
测试validate_name钩子
输入测试数据
{
"name": "jjj",
"sex": 2,
"age": 18
}
返回结果如下:
{
"name": [
"名字非法"
]
}
测试validate_sex钩子
输入测试数据
{
"name": "kkk",
"sex": 3,
"age": 18
}
返回结果如下:
{
"sex": [
"只能输入男和女"
]
}
测试默认的输入类型错误
输入测试数据
{
"name": "kkk",
"sex": "???",
"age": 18
}
返回结果如下:
{
"sex": [
"请填写合法的整数值。"
]
}
测试默认的必填项不填
输入测试数据
{
"name": "kkk"
}
返回结果如下:
{
"sex": [
"该字段是必填项。"
],
"age": [
"该字段是必填项。"
]
}
测试全局钩子
输入测试数据
{
"name": "kkk",
"sex": 1,
"age": 18
}
返回结果如下:
{
"age&sex": [
"男的必须22周岁以上才能结婚"
]
}
总结
- 设置必填与选填序列化字段,设置校验规则
- 为需要额外校验的字段提供局部钩子函数,如果该字段不入库,且不参与全局钩子校验,可以将值取出校验
- 为有联合关系的字段们提供全局钩子函数,如果某些字段不入库,可以将值取出校验
- 重写
create方法,完成校验通过的数据入库工作,得到新增的对象
Django(45)drf序列化类的使用(Serializer)的更多相关文章
- Django的DRF序列化方法
安装rest_framework -- pip install djangorestframework -- 注册rest_framework序列化 -- Python--json -- 第一版 用v ...
- Django(46)drf序列化类的使用(ModelSerializer)
前言 我们上篇文章使用到了Serializer类,可能有小伙伴说太过复杂,那么本篇就为大家带来更加简便的序列化类ModelSerializer ModelSerializer 先来看下ModelSer ...
- 067.Python框架Django之DRF视图类
一 关于视图类的一下概念 drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作.所以在django原有的django.views.View类基础上,drf封装了多个子类出来提供给我们使用. ...
- DRF框架(二)——解析模块(parsers)、异常模块(exception_handler)、响应模块(Response)、三大序列化组件介绍、Serializer组件(序列化与反序列化使用)
解析模块 为什么要配置解析模块 1)drf给我们提供了多种解析数据包方式的解析类 form-data/urlencoded/json 2)我们可以通过配置来控制前台提交的哪些格式的数据后台在解析,哪些 ...
- DRF 序列化组件
Serializers 序列化组件 Django的序列化方法 class BooksView(View): def get(self, request): book_list = Book.objec ...
- django rest_framework Serializers 序列化组件
为什么要用序列化组件 当我们做前后端分离的项目~~我们前后端交互一般都选择JSON数据格式,JSON是一个轻量级的数据交互格式. 那么我们给前端数据的时候都要转成json格式,那就需要对我们从数据库拿 ...
- [Django REST framework - 序列化组件、source、钩子函数]
[Django REST framework - 序列化组件.source.钩子函数] 序列化器-Serializer 什么是rest_framework序列化? 在写前后端不分离的项目时: 我们有f ...
- 写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用
写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用 一.了解什么是DRF DRF: Django REST framework Django REST framew ...
- python 全栈开发,Day95(RESTful API介绍,基于Django实现RESTful API,DRF 序列化)
昨日内容回顾 1. rest framework serializer(序列化)的简单使用 QuerySet([ obj, obj, obj]) --> JSON格式数据 0. 安装和导入: p ...
随机推荐
- 利用Apache部署静态网站(一)
Apache是世界使用排名第一的Web服务器软件.它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一.它快速.可靠并且可通过简单的API扩充, ...
- 哈工大LTP进阶使用-三元组事件抽取
哈工大LTP基本使用-分词.词性标注.依存句法分析.命名实体识别.角色标注 上一节我们讲了LTP的基本使用,接下来我们使用其进行事件抽取. 参考代码:https://github.com/liuhua ...
- Git 常用命令总结,将会持续更新
平常在windows电脑上使用Git Extensions 工具比较多,大部分的常用指令都可以通过点点点就可以完成.在mac电脑上的话使用sourcetree工具.但有时候也会直接通过git命令,很多 ...
- SEO优化技术的简介
严格来讲,seo技术没有所谓的严格的黑帽与白帽之分.即使是正常的301重定向,在某些情况下也能作用于黑帽seo技术.我们能判定一个人是真正的好人还是坏人么?答案是否定的.之所以解密所谓的黑帽seo,是 ...
- 0803-PyTorch的Debug指南
0803-PyTorch的Debug指南 目录 一.ipdb 介绍 二.ipdb 的使用 三.在 PyTorch 中 Debug 四. 通过PyTorch实现项目中容易遇到的问题 五.第八章总结 py ...
- [LeetCode每日一题]1143. 最长公共子序列
[LeetCode每日一题]1143. 最长公共子序列 问题 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度.如果不存在 公共子序列 ,返回 0 . 一个字符串 ...
- SQL必学必会笔记 —— 基础篇
基础篇 SQL语言按照功能划分 DDL(DataDefinitionLanguage),也就是数据定义语言,它用来定义我们的数据库对象,包括 数据库.数据表和列.通过使用DDL,可以创建,删除和修改数 ...
- QFNU-ACM 2020.04.05个人赛补题
A.CodeForces-124A (简单数学题) #include<cstdio> #include<algorithm> #include<iostream> ...
- J2SE基础题
J2SE基础 八种基本数据类型的大小,以及他们的封装类.(有的也说是9中基本数据类型,包括了void) 基本类型 大小(字节) 默认值 封装类 byte 1 (byte)0 Byte short 2 ...
- OO课程仓库部署使用GitLab CI
转自我的个人博客http://mistariano.com/blog/9 1. 服务器上安装 gitlab-runner 参考博客https://blog.csdn.net/qq_40699305/a ...