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. AI音乐创作,让每一个人都成为音乐家

    从录音带.MP3到专业的耳机.音箱,随着音乐消费方式的不断升级,音乐创作的专业"门槛"也在AI技术的加持下逐渐大众化,创作者的创新设计.创作频率也在持续增强,能降低创作门槛且智能化 ...

  2. Destination folder must be accessible

    问题 Ecplise拖入文件夹项目时提示错误:Destination folder must be accessible 解决 导入的时候包不能直接拖入,要使用import导入,选择File-> ...

  3. ArcGIS 添加Excel数据 报错 ArcGIS Failed to connect to database 外部数据库驱动程序(1)中的意外错误

    原因是因为 操作系统安装了一些补丁,卸载即可. 把以下补丁卸载掉即可. win7 <-- KB4041678 , KB4041681  --> SERVER 2008 R2 <-- ...

  4. 爬虫笔记之xpath

    目录 xpath如何取包含多个class属性 xpath获取当前标签下的所有文本(包括子标签) xpath如何取包含多个class属性 如果HTML结构是这样 <div class=" ...

  5. 使用VMware安装Linux(CentOS)操作系统

    使用VMware安装CentOS 6.4 环境:Windows7 , VMware Workstation10, CentOS6.4 为什么选择CentOS ? 主流: 目前的Linux操作系统主要应 ...

  6. 【离线数仓】Day02-用户行为数据仓库:分层介绍、环境搭建(hive、tez)、LZO压缩、建表查询导入加索引、编写脚本

    一.数仓分层概念 1.为什么要分层 ODS:原始数据层 DWD层:明细数据层 DWS:服务数据层 ADS:数据应用层 2.数仓分层 3.数据集市与数据仓库概念 4.数仓命名规范 ODS层命名为odsD ...

  7. bug处理记录:Error running 'WorkflowApplication': Command line is too long. Shorten command line for WorkflowApplication or also for Spring Boot default configuration?

    1.报错信息 Error running 'WorkflowApplication': Command line is too long. Shorten command line for Workf ...

  8. PyQt4编写界面的两种方式

    PyQt4编写界面的两种方式 应用PyQt4开发图形化界面有两种方式,一种是直接通过QtDesigner通过提供的窗口部件拖拽进行GUI创建,另外一种是直接进行编程实现. 第一种,QtDesigner ...

  9. Velero 系列文章(二):使用 Helm 安装 Velero

    概述 本文是通过 Helm 3 来安装 Velero, 只做最基本的安装.并计划将 YAML (只备份 YAML, 不备份 Volume) 备份到腾讯云的 COS(兼容 S3, 所以可以通过 AWS ...

  10. CCS选择器 选择器优先级 选择器常见属性

    目录 CSS前戏 1.css语法结构 2.css注释语法 3.引入css的多种方式 CSS基本选择器 1.标签选择器 2.类选择器 3.id选择器 4.通用选择器 CSS组合选择器 1.后代选择器(空 ...