rest_framework序列化,反序列化
序列化组件
from rest_framework.response import Response
1.Response本质也是继承了httpresponse,比httpResponse还强大,传入一个字典,列表可以序列化
2.会根据不同的请求客户端,返回不同的东西,如果是浏览器访问的话就返回一个页面,如果是手机端的话就返回数据
from django.db import models # Create your models here.
class Book(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
publish_date = models.DateField() publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
authors=models.ManyToManyField(to='Author')
def __str__(self):
return self.name class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField() class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField()
models.py
#在settings里面INSTALLED_APPS里面加入"rest_framework"
-序列化组件
-使用drf的序列化组件
from rest_framework.response import Response #(drf返回数据的时候使用)
新建一个文件夹app01下的serializer.py
-在视图中使用序列化的类
-1 实例化序列化的类产生对象,在产生对象的时候,传入需要序列化的对象(queryset)
-2 对象.data
-3 return Response(对象.data)
-高级用法:
-source:可以指定字段(name publish.name),可以指定方法,
-SerializerMethodField搭配方法使用(get_字段名字)
publish_detail=serializers.SerializerMethodField(read_only=True)
def get_publish_detail(self,obj):
return {'name':obj.publish.name,'city':obj.publish.city}
-read_only:反序列化时,不传
-write_only:序列化时,不显示
序列化的两种方式
-序列化的两种方式
-Serializers:没有指定表模型
-source:指定要序列化哪个字段,可以是字段,可以是方法
- SerializerMethodField的用法
authors=serializers.SerializerMethodField()
def get_authors(self,obj):
ret=AuthorSerializer(instance=obj.authors.all(),many=True)
return ret.data -ModelSerializers:指定了表模型
class Meta:
model=表模型
#要显示的字段
fields=('__all__')
fields=('id','name')
#要排除的字段
exclude=('name')
#深度控制
depth=1
-重写某个字段
在Meta外部,重写某些字段,方式同Serializers
反序列化
-反序列化
-使用继承了Serializers序列化类的对象,反序列化
-在自己写的序列化类中重写create方法
-重写create方法,实现序列化
-在序列化类中:
def create(self, validated_data):
ret=models.Book.objects.create(**validated_data)
return ret
-在视图中:
def post(self,request):
bookser=BookSerializer(data=request.data)
if bookser.is_valid():
ret=bookser.create(bookser.validated_data)
return Response() -使用继承了ModelSerializers序列化类的对象,反序列化
-在视图中:
def post(self,request):
bookser=BookSerializer(data=request.data)
if bookser.is_valid():
ret=bookser.save()
return Response()
反序列化的校验
-反序列化的校验
-validate_字段名(self,value):
-如果校验失败,抛出ValidationError(抛出的异常信息需要去bookser.errors中取)
-如果校验通过直接return value
-validate(self,attrs)
-attrs所有校验通过的数据,是个字典
-如果校验失败,抛出ValidationError
-如果校验通过直接return attrs
读一读源码
-全局和局部钩子源码部分
-在序列化的时候,传many=True和many=False,生成的对象并不是一个对象
-bookser.data
-之前执行过,直接返回
-get_attribute(instance, self.source_attrs)
-self.source_attrs 是source指定的通过 . 切分后的列表
-instance 当前循环到的book对象 views.py
from django.shortcuts import render,HttpResponse # Create your views here.
from rest_framework.views import APIView
from app01 import models
from rest_framework.serializers import Serializer from rest_framework.response import Response
from django.core import serializers
# 把对象转换成json格式字符串
from app01.app01serializer import BookSerializer
class Books(APIView):
def get(self,request):
response={'code':100,'msg':'查询成功'}
books=models.Book.objects.all()
#了解
# ret = serializers.serialize("json", books)
#如果序列化多条,many=True(也就是queryset对象,就需要写)
#如果序列化一条(可以不写)就是一个book对象,instance是要序列化的对象
bookser=BookSerializer(instance=books,many=True)
# print(type(bookser.data))
# bookser.data 是一个returnList的类型
response['data']=bookser.data
return Response(response) #response可以放returnlist也就是列表,也可以是字典,就是不能是对象
#使用继承了Serializers序列化类的对象,反序列化
# def post(self,request):
# #实例化产生一个序列化类的对象,data是要反序列化的字典
# # print(request.data)
# bookser=BookSerializer(data=request.data)
# if bookser.is_valid():
# #清洗通过的数据
# ret=bookser.create(bookser.validated_data)
#
# return Response()
#使用继承了ModelSerializers序列化类的对象,反序列化
def post(self,request):
#实例化产生一个序列化类的对象,data是要反序列化的字典
bookser=BookSerializer(data=request.data)
# bookser.data
if bookser.is_valid(raise_exception=True):
#清洗通过的数据
bookser.save()
else:
print(bookser.errors['name'][0])
return Response()
app01serializer.py from app01 import models
from rest_framework import serializers
class AuthorSerializer(serializers.Serializer):
name=serializers.CharField()
age=serializers.CharField()
# class BookSerializer(serializers.Serializer):
# #指定source='name' ,表示序列化模型表中的name字段,重名命为name5(name和source='name'指定的name不能重名)
# name5=serializers.CharField(source='name')
# #write_only 序列化的时候,该字段不显示
# #read_only 反序列化的时候,该字段不传
# price=serializers.CharField(write_only=True)
# #如果要取 出版社的city source='publish.city'
publish=serializers.CharField(source='publish.name')
# #source不但可以指定一个字段,还可以指定一个方法
# book_type = serializers.CharField(source='get_xx_display',read_only=True)
# #序列化出版社的详情,指定SerializerMethodField之后,可以对应一个方法,返回什么内容,publish_detail就是什么内容
publish_detail=serializers.SerializerMethodField(read_only=True)
# #对应的方法固定写法get_字段名
# def get_publish_detail(self,obj):
# # print(type(obj))
# return {'name':obj.publish.name,'city':obj.publish.city}
#
# #返回所有作者信息
authors=serializers.SerializerMethodField(read_only=True)
# def get_authors(self,obj):
# # return [ {'name':author.name,'age':author.age} for author in obj.authors.all()]
# authorser=AuthorSerializer(obj.authors.all(),many=True)
# return authorser.data
#
# def create(self, validated_data):
# ret=models.Book.objects.create(**validated_data)
# return ret
from rest_framework import exceptions
from app01 import models class BookSerializer(serializers.ModelSerializer):
class Meta:
model=models.Book
# fields=('nid','name')
#不能跟fields同时使用
# exclude=['name',]
fields=('__all__')
#深度是1,官方建议不要超过10,个人建议不要超过3
# depth=1
# xx=serializers.CharField(source='get_xx_display')
# authors=serializers.SerializerMethodField()
# def get_authors(self,obj):
# ret=AuthorSerializer(instance=obj.authors.all(),many=True)
# return ret.data
# name=serializers.CharField()
#反序列化的校验(局部校验,全局校验)
def validate_name(self,value): print(value)
raise exceptions.ValidationError('不能以sb开头')
# if value.startswith('sb'):
# raise ValidationError('不能以sb开头')
# return value def validate(self,attrs):
print(attrs)
# if attrs.get('price')!=attrs.get('xx'):
# raise exceptions.ValidationError('name和price相等,不正常')
return attrs
models.py
from django.db import models # Create your models here.
class Book(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
publish_date = models.DateField(null=True)
xx=models.IntegerField(choices=((0,'文学类'),(1,'情感类')),default=1,null=True)
publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE,null=True)
authors=models.ManyToManyField(to='Author')
def __str__(self):
return self.name
def test(self):
return 'xxx' class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField() class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField() def __str__(self):
return self.name
总结:
-django原生的序列化(了解)
-drf序列化:基本使用
-定义一个类BookSer,继承Serializers
-在类写字段
-name=serializer.CharField() -在视图中使用:
-book_ser=BookSer(instance=要序列化的对象,many=True)
-序列化之后的数据book_ser.data
-drf序列化类的两种写法
-继承Serializer
-每一个字段都需要自己写,跟表模型有对应关系,source:指定的是表模型中哪个字段(可以指定字段,可以指定方法)
-SerializerMethodField 跟它绑定一个方法(get_字段名),方法返回什么,该字段就是什么
-继承ModelSerializer
-重写字段
class Meta:
model=表模型
fields='__all__'
fields=(字段一,字段二)
exclude=(排除的字段)
depth=1 :尽量少用
-反序列化
-继承Serializer
-重写create方法,自己写保存逻辑 -继承ModelSerializer
-不管是新增还是修改,都调用save方法
-校验:
-局部:validate_字段名(self,value):
-全局:validate(self,attrs)
-源码分析
-数据校验部分源码
-序列化类实例化产生对象时走的逻辑
-many控制生成的对象是什么
-序列化的时候,走的逻辑
rest_framework序列化,反序列化的更多相关文章
- django rest_framework 序列化组件详解
为什么要用序列化组件 当我们做前后端分离的项目,我们前后端交互一般都选择JSON数据格式,JSON是一个轻量级的数据交互格式. 那么我们给前端数据的时候都要转成json格式,那就需要对我们从数据库拿到 ...
- 5) ModelSerializer(重点) 基表 测试脚本 多表关系建外键 正反查 级联 插拔式连表 序列化反序列化整合 增删查 封装response
一.前戏要做好 配置:settings.py #注册drf INSTALLED_APPS = [ # ... 'api.apps.ApiConfig', 'rest_framework', ] # ...
- php json与xml序列化/反序列化
在web开发中对象的序列化与反序列化经常使用,比较主流的有json格式与xml格式的序列化与反序列化,今天想写个jsop的小demo,结果发现不会使用php序列化,查了一下资料,做个笔记 简单数组js ...
- 序列化反序列化api(入门级)
定义: java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 为什么字符串通常也会进行序列化? 对象需要进行序列化的原因:保证对象的状态不变 ...
- python_way ,day5 模块,模块3 ,双层装饰器,字符串格式化,生成器,递归,模块倒入,第三方模块倒入,序列化反序列化,日志处理
python_way.day5 1.模块3 time,datetime, json,pickle 2.双层装饰器 3.字符串格式化 4.生成器 5.递归 6.模块倒入 7.第三方模块倒入 8.序列化反 ...
- C#之你懂得的序列化/反序列化
前言:写此文章一方面是为了巩固对序列化的认识,另一方面是因为本人最近在面试,面试中被问到“为什么要序列化”.虽然一直在使用,自己也反复的提到序列化,可至于说为什么要序列化,还真的没想过,所以本文就这样 ...
- springboot学习(三)——http序列化/反序列化之HttpMessageConverter
以下内容,如有问题,烦请指出,谢谢! 上一篇说掉了点内容,这里补上,那就是springmvc的http的序列化/反序列化,这里简单说下如何在springboot中使用这个功能. 使用过原生netty ...
- java序列化反序列化深入探究
When---什么时候需要序列化和反序列化: 简单的写一个hello world程序,用不到序列化和反序列化.写一个排序算法也用不到序列化和反序列化.但是当你想要将一个对象进行持久化写入文件,或者你想 ...
- java序列化反序列化深入探究(转)
When---什么时候需要序列化和反序列化: 简单的写一个hello world程序,用不到序列化和反序列化.写一个排序算法也用不到序列化和反序列化.但是当你想要将一个对象进行持久化写入文件,或者你想 ...
随机推荐
- test 5.1 高精度小数(10分)
请写一个程序,输入一个分数,计算出它的小数形式.无论是否可以除尽,输出最多小数点后200位. 题目内容 由于计算机内部表达方式的限制,浮点运算都有精度问题,为了得到高精度的计算结果,就需要自己设计实现 ...
- Go基础学习(二)
数组[array] 数组定义[定义后长度不可变] 12 symbol := [...]string{USD: "$", EUR: "€", GBP: " ...
- 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(11.2)- FlexSPI NOR连接方式大全(RT1060/1064(SIP))
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT1060/1064(SIP)两款MCU的FlexSPI NOR启动的连接方式. 上一篇文章<FlexSPI N ...
- CountDownLatch源码探究 (JDK 1.8)
CountDownLatch能够实现让线程等待某个计数器倒数到零的功能,之前对它的了解也仅仅是简单的使用,对于其内部如何实现线程等待却不是很了解,最好的办法就是通过看源码来了解底层的实现细节.Coun ...
- http协议概览
这里我只是对一些知识进行简单的整理,方便自己理解记忆,还有很多不完善的地方,更多细节,需要查看书籍或者其他文章 http协议的发展过程 HTTP 是基于 TCP/IP 协议的应用层协议.它不涉及数据包 ...
- JZOJ 5305. 【NOIP2017提高A组模拟8.18】C (Standard IO)
5305. [NOIP2017提高A组模拟8.18]C (Standard IO) Time Limits: 1000 ms Memory Limits: 131072 KB Description ...
- 峰哥说技术:06-手撸Spring Boot自定义启动器,解密Spring Boot自动化配置原理
Spring Boot深度课程系列 峰哥说技术—2020庚子年重磅推出.战胜病毒.我们在行动 06 峰哥说技术:手撸Spring Boot自定义启动器,解密Spring Boot自动化配置原理 Sp ...
- ES6引入的Reflect对象目的何在?
Reflect对象其实就是为了取代Object对象.取代原因有一下几点: 1)Object对象的一些内部方法放在了Reflect上面,比如:Object.defineProperty.主要是优化了语言 ...
- 使用twisted将mysql插入变成异步执行
python 异步MySQL存库 对于异步框架而言,这些延迟是无法接受的.因此, Twisted 提供了 twisted.enterprise.adbapi, 遵循DB-API 2.0协议的一个异 ...
- Go 的 http 包的源码,通过代码我们可以看到整个的 http 处理过程
func (srv *Server) Serve(l net.Listener) error {defer l.Close() var tempDelay time.Duration // how l ...