序列化,反序列化

Posted huangxuanya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了序列化,反序列化相关的知识,希望对你有一定的参考价值。


昨日回顾:
-Django的请求生命周期
-CBV源码分析
-类名.as_view()---->执行结果返回内存地址---》内存函数view的内存地址---》请求路径跟路由匹配成,会调用view(request)
view()内部调用了self.disaptch---->根据请求不同,执行不同的方法

-restful规范:
-10
-1 路径中资源都名词,可以用复数
-2 通过请求方式来执行不同操作
-3 返回状态码
-4 返回错误信息
-5 返回的数据中带链接
-用原生django写restful的接口
-drf
-使用:
-1 在setting.py 中把rest_framework加入到app中
-2 以后再写全写CBV,继承APIView
-源码分析:
-APIView:重写了dispatch方法:1 包装request 2 加入了一些校验
-Request对象:重写了__getattr__ query_params FILES request.data


今日内容:
#在settings里面INSTALLED_APPS里面加入"rest_framework"
-序列化组件
-使用drf的序列化组件
from rest_framework.response import Response #(drf返回数据的时候使用)
#Response 本质也是继承了httpresponse,只不过比jsonresponse还要强大,里面直接传一个字典给你序列化,还会根据你请求的方式,
# 客户端如果是浏览器话就会返回一个页面,如果是手机端的话就会返回字典数据

#models中加入一个个表
#然后做数据迁移
#pulish和book表里添加数据
#view里面的话采用了另外一种方式(不推荐,会显示在页面上乱码)
#新建一个文件夹app01 serializer
#在view里写代码
-1 新建一个序列化类继承Serializer
-2 在类中写要序列化的字段

-在视图中使用序列化的类
-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对象

技术图片
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()
views.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
app01serializer.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
models.py

 


以上是关于序列化,反序列化的主要内容,如果未能解决你的问题,请参考以下文章

反序列化为啥要找公开方法

ctf serialize 序列化和反序列化

如何序列化/反序列化的ArrayList

C# JSON 反序列化

xmldecoder反序列化漏洞分析

NewtonSoft.JSON 反序列化 - 未正确反序列化。 (VB.NET)