序列化组件

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序列化,反序列化的更多相关文章

  1. django rest_framework 序列化组件详解

    为什么要用序列化组件 当我们做前后端分离的项目,我们前后端交互一般都选择JSON数据格式,JSON是一个轻量级的数据交互格式. 那么我们给前端数据的时候都要转成json格式,那就需要对我们从数据库拿到 ...

  2. 5) ModelSerializer(重点) 基表 测试脚本 多表关系建外键 正反查 级联 插拔式连表 序列化反序列化整合 增删查 封装response

    一.前戏要做好 配置:settings.py #注册drf INSTALLED_APPS = [ # ... 'api.apps.ApiConfig', 'rest_framework', ] ​ # ...

  3. php json与xml序列化/反序列化

    在web开发中对象的序列化与反序列化经常使用,比较主流的有json格式与xml格式的序列化与反序列化,今天想写个jsop的小demo,结果发现不会使用php序列化,查了一下资料,做个笔记 简单数组js ...

  4. 序列化反序列化api(入门级)

    定义: java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 为什么字符串通常也会进行序列化? 对象需要进行序列化的原因:保证对象的状态不变 ...

  5. python_way ,day5 模块,模块3 ,双层装饰器,字符串格式化,生成器,递归,模块倒入,第三方模块倒入,序列化反序列化,日志处理

    python_way.day5 1.模块3 time,datetime, json,pickle 2.双层装饰器 3.字符串格式化 4.生成器 5.递归 6.模块倒入 7.第三方模块倒入 8.序列化反 ...

  6. C#之你懂得的序列化/反序列化

    前言:写此文章一方面是为了巩固对序列化的认识,另一方面是因为本人最近在面试,面试中被问到“为什么要序列化”.虽然一直在使用,自己也反复的提到序列化,可至于说为什么要序列化,还真的没想过,所以本文就这样 ...

  7. springboot学习(三)——http序列化/反序列化之HttpMessageConverter

    以下内容,如有问题,烦请指出,谢谢! 上一篇说掉了点内容,这里补上,那就是springmvc的http的序列化/反序列化,这里简单说下如何在springboot中使用这个功能. 使用过原生netty ...

  8. java序列化反序列化深入探究

    When---什么时候需要序列化和反序列化: 简单的写一个hello world程序,用不到序列化和反序列化.写一个排序算法也用不到序列化和反序列化.但是当你想要将一个对象进行持久化写入文件,或者你想 ...

  9. java序列化反序列化深入探究(转)

    When---什么时候需要序列化和反序列化: 简单的写一个hello world程序,用不到序列化和反序列化.写一个排序算法也用不到序列化和反序列化.但是当你想要将一个对象进行持久化写入文件,或者你想 ...

随机推荐

  1. O2O倒逼汽车行业改革:服务超越销售成重心

    汽车作为越来越普及的出行工具,已经进入千家万户.与其他家具.家电.服饰等产品不同,从新车销售到售后保养.保险购买.维修乃至报废阶段,都能细分化,形成一个个潜力巨大的垂直领域.而随着互联网元素的渗入,汽 ...

  2. HDU——算法练习1000 1089-1096

    全篇都是讲数字之间的运算的: 由上自下难度逐渐升级 ,没耐心者建议一拉到底: 1000: Problem Description Calculate A + B.   Input Each line ...

  3. percona-toolkit 之 【pt-query-digest】使用

    背景 关于pt-query-digest的使用场景和方法在percona-toolkit 之 [pt-query-digest]介绍文章里已经做了详细说明,现在开始介绍下如何使用,以及常用的命令. 使 ...

  4. 基于activity的强大java工作流引擎,可视化开发工作流

    我们先来看看工作流引擎和Activity? 工作流引擎 所谓工作流引擎是指workflow作为应用系统的一部分,并为之提供对各应用系统有决定作用的根据角色.分工和条件的不同决定信息传递路由.内容等级等 ...

  5. Spring常见注解

    @Autowired @Resource @Component:类加上@Component注解,即表明此类是bean @Aspect 注解表示这是一个切面 @Around(value = " ...

  6. ORACLE数据库实现主键自增

    ORACLE数据库是甲骨文公司的一款关系数据库管理系统. 实现主键自动增长需要四个步骤: 去看 创建表格 去看 创建自增序列 去看 创建触发器 去看 插入测试 1.创建表格(必须有主键) -- 创建学 ...

  7. 面向web前端及node开发人员的vim配置

    鉴于 window 下基本用不到 vim,所以下面内容不再提及 window,具体可以在相应 github 中查看手册操作基础:已装有上有 nodejs(npm).没装的可以移步官网:https:// ...

  8. JS基础入门篇(二十)—事件对象以及案例(二)

    案例一.点击按钮,选中input中的全部内容 select()方法:选中全部. 点击按钮选中输入框中的内容!!!! <!DOCTYPE html> <html lang=" ...

  9. PHP 深度理解preg_quote()函数

    php手册上说,preg_quote()函数的作用是转义正则表达式字符.那么下面我们来深入了解下这个函数是怎么使用的: 说明:preg_quote()函数常和preg_replace()函数一起使用. ...

  10. iOS应用构建与部署小结

    注:本文首发于我的个人博客:https://evilpan.com/2019/04/06/ios-basics/ 上篇文章介绍了Objective-C的基本概念,本文就来接着看如何创建我们的第一个简单 ...