1.序列化类常用字段和字段参数

1.1 常用字段类

1.BooleanField
2 NullBooleanField
3 CharField CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
4 EmailField EmailField(max_length=None, min_length=None, allow_blank=False)
5 RegexField RegexField(regex, max_length=None, min_length=None, allow_blank=False)
6 SlugField SlugField(max_length=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+
7 URLField URLField(max_length=200, min_length=None, allow_blank=False)
8 UUIDField UUIDField(format=’hex_verbose’) format: 1)
9 IPAddressField IPAddressField(protocol=’both’, unpack_ipv4=False, **options)
10 IntegerField IntegerField(max_value=None, min_value=None)
11 FloatField FloatField(max_value=None, min_value=None)
12 DecimalField DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置
13 DateTimeField DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
14 DateField DateField(format=api_settings.DATE_FORMAT, input_formats=None)
15 TimeField TimeField(format=api_settings.TIME_FORMAT, input_formats=None)
16 DurationField DurationField()
17 ChoiceField ChoiceField(choices) choices与Django的用法相同
18 MultipleChoiceField MultipleChoiceField(choices)
19 FileField FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
20 ImageField ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)

1.2重要字段类型

CharField
IntegerField
DecimalField
DateTimeField
BooleanField
ListField
DictField

1.3 常用字段参数

1.CharField及其子类(哪些类的父类是CharField需要在源码中查看)的字段参数:
max_length:最大长度
min_length:最小长度
allow_blank:是否允许为空
trim_whitespace 是否截断空白字符 2.InterField参数:
max_value:最大值
min_value:最小值 3.所有字段都有的的参数:
required:表明该字段在反序列化时必须输入,默认True
default:反序列化时使用的默认值
allow_null:表名该字段是否允许传入None,默认Flase
validators:该字段使用的验证器
error_messages:包含错误编号与错误信息的字典
label:用于HTML展示API页面时,显示的字段名称
help_text:用于HTML展示API页面时,显示的字段帮助提示信息 read_only:表明该字段仅用于序列化输出,默认Flase
write_only:表明该字段仅用于反序列化的输入,默认Flase 4.反序列化校验执行流程:
1.先执行字段自身的校验规则:max_length,max_value
2.再执行验证器validators
3.局部钩子校验规则
4.全局钩子校验规则

2.序列化高级用法之source

models.py:
先创建表,表之间存在数据库层面的联系:
from django.db import models class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32)
publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author') class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32) class Author(models.Model):
name = models.CharField(max_length=32)
phone = models.CharField(max_length=11) serializer.py:
from rest_framework import serializers class BookSerializer(serializers.Serializer):
# 自有字段,直接点名字,通过sourse可以指定models.py中某张表的字段
name_zzz = serializers.CharField(max_length=8,source='name')
real_price = serializers.CharField(source='price')
# 一对多,需要先点外键名到那张表,再点那张表的名字
publish = serializers.CharField(source='publish.name')
# 多对多,不能用sourse
authors = serializers.CharField() views.py:
from app01.serializer import BookSerializer
from .models import Book
from rest_framework.response import Response
from rest_framework.views import APIView class BookView(APIView):
def get(self,request):
book_queryset = Book.objects.all()
ser = BookSerializer(instance=book_queryset,many=True)
return Response(ser.data)
"""
通过以上代码演示效果:在serializer.py中无论字段名起什么,只要括号中的source对应models某张表中的某些字段名,在前端就可以显示该名字。它们之间在views.py中通过视图类连接。
"""

3.序列化高级用法之定制字段的两种方式

以上代码存在局限性:首先我们查到出版社,但是我们只能拿到出版社姓名,无法拿到出版社其他信息,其次多对多关系的作者信息我们没法拿到。我们需要通过以下方法来解决。

3.1SerializerMethodField定制

SerializerMethodField是一个定制返回格式的字段类型,该字段类型中不需要填写任何参数,但是方法需要通过写函数来定制指定的返回的格式。返回的数据遵循restful规范:一对多显示字典,多对多显示列表套字典。
serializer.py:
from rest_framework import serializers class BookSerializer(serializers.Serializer):
name_zzz = serializers.CharField(max_length=8, source='name')
real_price = serializers.CharField(source='price') publish_detail = serializers.SerializerMethodField()
# 函数名要和字段名保持一致,该字段名也是前端展示的字段名
def get_publish_detail(self, obj):
return {'name': obj.publish.name, 'addr': obj.publish.addr} author_list = serializers.SerializerMethodField() def get_author_list(self,obj):
l = []
for author_obj in obj.authors.all():
l.append({'name':author_obj.name,'phone':author_obj.phone})
return l
models.py以及views.py代码和上步一样。

3.2在表模型中定制

moodels.py:
from django.db import models class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32) publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author')
# 在表模型中定制的函数名要和serializer.py中的字段名保持一致。
@property
def publish_detail(self):
return {'name':self.publish.name,'addr':self.publish.addr}
# 定制的函数要用@property修饰,可以将方法伪装成一个数据。
@property
def author_list(self):
l = []
for author_obj in self.authors.all():
l.append({'name':author_obj.name,'phone':author_obj.phone})
return l class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32) class Author(models.Model):
name = models.CharField(max_length=32)
phone = models.CharField(max_length=11) seriializer.py:
from rest_framework import serializers class BookSerializer(serializers.Serializer):
name_zzz = serializers.CharField(max_length=8, source='name')
real_price = serializers.CharField(source='price')
#DictField和ListField用来接收表格类中返回的数据中的字典类型和列表类型
publish_detail = serializers.DictField() author_list = serializers.ListField()

4.多表关联反序列化保存

4.1 反序列化字段校验步骤

1.字段自己的:name = serializers.CharField(max_length=8, error_messages={'max_length': '太长了'})
2.validators=[方法](使用频率较低)
3.局部钩子
4.全局钩子
"""
代码走到if ser.is_valid():时就会走以上反序列化校验代码。
"""

4.2 新增图书接口

# 前端传入数据的格式:{"name":"新阿q正传","price":"88.66","publish":1,"authors":[2]}
models.py:
from django.db import models class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32) publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author') @property
def publish_detail(self):
return {'name':self.publish.name,'addr':self.publish.addr} @property
def author_list(self):
l = []
for author_obj in self.authors.all():
l.append({'name':author_obj.name,'phone':author_obj.phone})
return l class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32) class Author(models.Model):
name = models.CharField(max_length=32)
phone = models.CharField(max_length=11) seriializer.py:
from rest_framework import serializers
from .models import Book class BookSerializer(serializers.Serializer):
# name和price即用来做序列化,也用来做反序列化,既读又写,所以不用加read_only,write_only
name = serializers.CharField(max_length=8)
price = serializers.CharField() # 用来做序列化,所以要加上read_only=True
publish_detail = serializers.DictField(read_only=True)
author_list = serializers.ListField(read_only=True) # 用来做反序列化,要加上write_only=True,如果不加会在前端看到该字段
publish = serializers.CharField(write_only=True)
authors = serializers.ListField(write_only=True) # 新增要重写create方法
def create(self, validated_data):
# print(validated_data) {'name': '阿q正传', 'price': '66.66', 'publish': '1', 'authors': [1, 2]}
# 因为前端上传的是publish的id,所以需要用publish_id=validated_data.get('publish')来新增,如果是对象可以直接用publish新增
# 取数据的键需要和前端传过来字典的键保持一致
book_obj = Book.objects.create(name=validated_data.get('name'),price=validated_data.get('price'),publish_id=validated_data.get('publish'))
# 第三张表要手动写代码新增,一个*数打散列表,两个*用来打散字典
book_obj.authors.add(*validated_data.get('authors'))
return book_obj views.py:
class BookView(APIView):
def get(self,request):
book_queryset = Book.objects.all()
ser = BookSerializer(instance=book_queryset,many=True)
return Response(ser.data) def post(self,request):
# print(request.data)
ser = BookSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code':100,'msg':'新增成功'})
else:
return Response({'code':101,'msg':ser.errors}) 前端数据上传尽量使用JSON格式,发现数据新增成功:

4.3 修改图书接口

# 前端传入数据的格式:{"name":"新阿q正传","price":"88.66","publish":1,"authors":[2]}

models.py:
from django.db import models class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32) publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author') @property
def publish_detail(self):
return {'name':self.publish.name,'addr':self.publish.addr} @property
def author_list(self):
l = []
for author_obj in self.authors.all():
l.append({'name':author_obj.name,'phone':author_obj.phone})
return l class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32) class Author(models.Model):
name = models.CharField(max_length=32)
phone = models.CharField(max_length=11) views.py:
class BookDetailView(APIView):
def put(self,request,pk):
book_obj = Book.objects.filter(pk=pk).first()
ser = BookSerializer(data=request.data,instance=book_obj)
if ser.is_valid():
# save需要手动在BookSerializer类中写update方法
ser.save()
return Response({'code':100,'msg':'修改成功'})
else:
return Response({'code':101,'msg':ser.errors}) serializer.py:
from rest_framework import serializers
from .models import Book class BookSerializer(serializers.Serializer):
name = serializers.CharField(max_length=8)
price = serializers.CharField() # 用来做序列化
publish_detail = serializers.DictField(read_only=True)
author_list = serializers.ListField(read_only=True) # 用来做反序列化
publish = serializers.CharField(write_only=True)
authors = serializers.ListField(write_only=True) def create(self, validated_data):
print(validated_data)
book_obj = Book.objects.create(name=validated_data.get('name'),price=validated_data.get('price'),publish_id=validated_data.get('publish'))
book_obj.authors.add(*validated_data.get('authors'))
return book_obj def update(self, instance, validated_data):
# print(validated_data) # {'name': '新阿q正传', 'price': '88.66', 'publish': '1', 'authors': [2]}
# uodate方法中instance就是book对象
instance.name = validated_data.get('name')
instance.price = validated_data.get('price')
instance.publish_id = validated_data.get('publish') #多对多关系在第三张表上,最好先删除,再写入
instance.authors.clear()
instance.authors.add(*validated_data.get('authors'))
# update方法写完依旧要用修改后的对象点save(),然后返回
instance.save()
return instance

5.ModelSerializer使用

ModelSerializer继承自Serializer,完成了很多操作,是之前BookSerializer的简化版:
-跟表模型强关联
-大部分请求,不用写create和update了 serializer.py:
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from .models import Book class BookSerializer(serializers.ModelSerializer):
class Meta:
# 和Book表绑定
model = Book
# 中括号内的字段名要和extra_kwargs中的字段名保持一致,并且和models.py中的Book表中的字段名保持一致。
fields = ['name', 'price', 'publish_detail', 'author_list', 'publish', 'authors']
# 定制限制信息
extra_kwargs = {
'name': {'max_length': 8},
'publish_detail': {'read_only': True},
'author_list': {'read_only': True},
'publish': {'write_only': True},
'authors': {'write_only': True}
}
# 写钩子函数,要和class Meta:保持相同的缩进
def validate_name(self, name):
if name.startswith('sb'):
raise ValidationError('不能sb') else:
return name models.py:
from django.db import models class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32) publish = models.ForeignKey(to='Publish',on_delete=models.CASCADE)
authors = models.ManyToManyField(to='Author') @property
def publish_detail(self):
return {'name':self.publish.name,'addr':self.publish.addr} @property
def author_list(self):
l = []
for author_obj in self.authors.all():
l.append({'name':author_obj.name,'phone':author_obj.phone})
return l class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32) class Author(models.Model):
name = models.CharField(max_length=32)
phone = models.CharField(max_length=11) views.py:
from app01.serializer import BookSerializer
from .models import Book
from rest_framework.response import Response
from rest_framework.views import APIView class BookView(APIView):
def get(self,request):
book_queryset = Book.objects.all()
ser = BookSerializer(instance=book_queryset,many=True)
return Response(ser.data) def post(self,request):
# print(request.data)
ser = BookSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code':100,'msg':'新增成功'})
else:
return Response({'code':101,'msg':ser.errors}) class BookDetailView(APIView):
def put(self,request,pk):
book_obj = Book.objects.filter(pk=pk).first()
ser = BookSerializer(data=request.data,instance=book_obj)
if ser.is_valid():
ser.save()
return Response({'code':100,'msg':'修改成功'})
else:
return Response({'code':101,'msg':ser.errors})

drf-序列化字段及参数、序列化和反序列化高级用法、ModelSerializer使用的更多相关文章

  1. MyBatis动态传入表名,字段名参数的解决办法---statementType用法

    statementType="STATEMENT" 要实现动态传入表名.列名,需要做如下修改 添加属性statementType="STATEMENT" 同时s ...

  2. 0012 基于DRF框架开发(04 序列化器的字段与选项)

    1 常用字段类型 字段 构造方式 BooleanField BooleanField() NullBooleanField NullBooleanField() CharField CharField ...

  3. DRF序列化和反序列化(二:ModelSerializer)

    一: rest_framework 中 serializers.Serializer的不方便之处(以下简称Serializer) a:需要定义每一个字段,并且这个字段是和models字段及其类似. b ...

  4. DRF(2) - 解析器,序列化组件使用(GET/POST接口设计)

    一.DRF - 解析器 1.解析器的引出 我们知道,浏览器可以向django服务器发送json格式的数据,此时,django不会帮我们进行解析,只是将发送的原数据保存在request.body中,只有 ...

  5. Newtonsoft.Json高级用法,json序列号,model反序列化,支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity,字符串

    原文地址:https://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口 ...

  6. JSON数据处理框架Jackson精解第一篇-序列化与反序列化核心用法

    Jackson是Spring Boot默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库.有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的,没有这种限制.它提供了很 ...

  7. Newtonsoft.Json高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的字段名称

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

  8. Python之Suds库调用WCF时复杂参数序列化

    今天主要做自动化测技术支持工作,最近一直在做接口自动化这块,前些天在研究将web页面模拟http进行接口自动化,这周杭州那边想测试WCF服务,所以这两天一直在探索.遇到的第一个问题就是服务参数传参序列 ...

  9. Python之Suds库调用WCF实现复杂参数序列化

    今年主要做自动化测技术支持工作,最近一直在做接口自动化这块,前些天在研究将web页面模拟http进行接口自动化,这周杭州那边想测试WCF服务,所以这两天一直在探索.遇到的第一个问题就是服务参数传参序列 ...

  10. 编写高质量代码改善C#程序的157个建议——建议54:为无用字段标注不可序列化

    建议54:为无用字段标注不可序列化 序列化是指这样一种技术:把对象转变成流.相反过程,我们称为反序列化.在很多场合都需要用到这项技术. 把对象保存到本地,在下次运行程序的时候,恢复这个对象. 把对象传 ...

随机推荐

  1. Go语言核心36讲01

    你好,我是郝林,今天我分享的内容是:0基础的你,如何开始入门学习Go语言. 1. 你需要遵循怎样的学习路径来学习Go语言? 我们发现,订阅本专栏的同学们都在非常积极的学习和讨论,这让我们非常欣慰,并且 ...

  2. UBOOT编译--- UBOOT编译过程目标依赖分析(八)

    1. 前言 UBOOT版本:uboot2018.03,开发板myimx8mmek240. 2. 概述 本文采用自顶向下的方法,从顶层目标开始到最原始的依赖. 3. u-boot编译 uboot的编译分 ...

  3. 模块/os/sys/json

    目录 内容概要 1.os模块 2.sys模块 3.json模块/实战 内容概要 os模块 sys模块 json模块/实战 1.os模块 # os模块主要是与我们的操作系统打交道 1.创建文件夹(目录) ...

  4. MySQL 常用到的几个字符处理函数

    修改某字段的内容,用于英文 首先解释用到的函数: CONCAT(str1,str2)字符连接函数 UPPER(str)将字符串改为大写字母 LOWER(str)将字符串改为小写字母 LENGTH(st ...

  5. .NET 6 实现滑动验证码(二)、基本数据

    上一节,介绍了滑动验证码的基本情况,也创建了一个.NET 6的工程.本节内容是创建一些基础类. 目录 CaptchaData.cs CaptchaValidateData.cs ImageCaptch ...

  6. 第2-4-10章 规则引擎Drools实战(3)-保险产品准入规则

    目录 9.3 保险产品准入规则 9.3.1 决策表 9.3.2 规则介绍 9.3.3 实现步骤 9.3 保险产品准入规则 全套代码及资料全部完整提供,点此处下载 9.3.1 决策表 前面我们编写的规则 ...

  7. 第二章:seaborn调色板

    1.系统默认调色板 1 import seaborn as sns 2 import matplotlib.pyplot as plt 3 4 # 设置画布的大小 5 sns.set(context= ...

  8. 【Java EE】Day05 JDBC概念、对象、控制事务

    一.基本概念 1.概念 Java Database Connectivity:Java数据库连接 2.本质 SUN公司提供的操作所有关系型数据库的规则,是一套接口 各厂商实现此接口,提供相应的驱动ja ...

  9. 【JUC】循环屏障CyclicBarrier详解

    欢迎关注专栏[JAVA并发] 前言 jdk中提供了许多的并发工具类,大家可能比较熟悉的有CountDownLatch,主要用来阻塞一个线程运行,直到其他线程运行完毕.而jdk还有一个功能类似并发工具类 ...

  10. 详记apache-poi的使用,将word,excel,ppt转换为html

    原文:https://blog.51cto.com/yunyaniu/5210961 java:Java的jar包之POI的简介.安装.使用方法(基于POI的转换-Word.Excel.Ppt等转ht ...