rest_framework序列化,反序列化

序列化组件

from rest_framework.response import Response1.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控制生成的对象是什么      -序列化的时候,走的逻辑

 

原文地址:https://www.cnblogs.com/huangxuanya/p/11143394.html

时间: 2024-11-03 07:27:39

rest_framework序列化,反序列化的相关文章

drf 序列化 反序列化

准备: 配置:settings.py INSTALLED_APPS = [ 'rest_framework', ] DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'dg_proj', 'USER': 'root', 'PASSWORD': '123', } } LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai' USE_I18N = True

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

一.前戏要做好 配置:settings.py #注册drf INSTALLED_APPS = [ # ... 'api.apps.ApiConfig', 'rest_framework', ] ? #配置数据库 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'dg_proj', 'USER': 'root', 'PASSWORD': '123', } } """ 在任何(根或者

序列化反序列化

对Java对象序列化的目的是持久化对象或者为RMI(远程方法调用)传递参数和返回值. 下面是一个序列化对象写入文件的例子: ---------------------------- 1 package utils; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.O

protostuff序列化/反序列化

Protostuff是基于Google protobuff技术的Java版本,直接使用原生的protobuff是需要数据结构的预编译过程,需要编写.proto格式的配置文件,再通过protobuff提供的工具翻译成目标语言代码,而Protostuff动态支持了protobuff的预编译的过程,可以直接使用普通java POJO进行序列化,简化编码. 经过实测序列化性能相对原生protpbuff没有影响. 由于Protostuff只支持Java实现,不过并未对序列化格式有做任何修改,所以Proto

.net 序列化反序列化

.net 序列化创建对象的深拷贝 public static object DeepClone(object original) { using (MemoryStream stream = new MemoryStream()) { //构造序列化格式化器来执行所有实习工作 BinaryFormatter formatter = new BinaryFormatter(); //流上下文 formatter.Context = new StreamingContext(StreamingCon

.NET序列化反序列化总结

一直想写这个专题,但是工作后人很懒散,总下不了决心,今天一个人在家就写下来. 关于序列化,可以总结出它的作用有以下几点: 1.记录应用程序的状态,在下次启动时还原上次的状态. 2.进程之间的通信,如使用socket编程时使用.这里的进程包括同一台主机之间进程的通信,也包括不同主机之间的通信. 3.作为对象的深拷贝的一种实现方式. .net中的序列化支持下面几种序列化机制: 1.使可序列化的类型序列化和反序列化 2.控制可序列化的类型的序列化/反序列化内容和过程 3.将类型序列化/反序列化为不同的

常用json序列化/反序列化技术对比测试

目前常用的json工具有:1.json-lib:2.jakson-mapper:3.fastjson. 下面对这三种工具的性能进行简单对比测试. 测试样本:一个126K的json文件,内容为json数组. 测试方法:反序列化,读取文件中的json转化为java对象. 测试代码如下: 1 @Test 2 public void testDeserialize() throws Exception { 3 String dealer = "d:\\auto\\json\\100016109.js&q

序列化反序列化的一些可用种类

1.java自带的 2.kryo 3.FST 4.protostuff protobuf的一个缺点是需要数据结构的预编译过程,首先要编写.proto格式的配置文件,再通过protobuf提供的工具生成各种语言响应的代码.由于java具有反射和动态代码生成的能力,这个预编译过程不是必须的,可以在代码执行时来实现.有个protostuff(http://code.google.com/p/protostuff/)已经实现了这个功能. protostuff基于Google protobuf,但是提供了

10.8-全栈Java笔记:序列化/反序列化的步骤和实例

本节我们详细讲解10.3节中提到的序列化和反序列化操作. 序列化和反序列化是什么 当两个进程远程通信时,彼此可以发送各种类型的数据. 无论是何种类型的数据,都会以二进制序列的形式在网络上传送.比如,我们可以通过http协议发送字符串信息:我们也可以在网络上直接发送JAVA对象.发送方需要把这个Java对象转换为字节序列,才能在网络上传送:接收方则需要把字节序列再恢复为Java对象. 把Java对象转换为字节序列的过程称为对象的序列化.把字节序列恢复为Java对象的过程称为对象的反序列化. 对象序