序列化组件

django自带的有序列化组件不过不可控不建议使用(了解)

from django.core import serializers 

class Books(APIView):
    def get(self,request):
        response = {'code':100,'msg':'查询成功'}
        books = models.Book.objects.all()
        # 了解django自带的序列化组件
        ret= serializers.serialize("json",books)
        return HttpResponse(ret)

 

使用drf的序列化组件

  自定义py文件里为了和view视图函数隔离开 自定义文件中写serializer组件

    1 新建一个序列化类继承Serializer   2  在类中写序列化的字段

      source='表中字段'  自定义的字段不能和表中的字段名一样 

      source的值传给了默认形参instance 视图函数中的instance可以不写  

      source可以写跨表字段'publish.name'  之前跨表是book.publish.name 现在用source就可以省略book了 写成publish.name  

      source不但可以指定一个字段 还可以指定一个方法 

#自定义的py文件中

from rest_framework import serializers    #序列化组件


class BookSerializer(serializers.Serializer):
# 指定source = 'name' 表示序列化模型表中的name字段 重命名为name5(name5这个字段名 和source=’name'指定的模型表中的name字段名不能一样)
    name5 = serializers.CharField(source='name')
    # write_only 序列化的时候,该字段前端不显示
    # read_only   反序列化的时候,该字段不传 前端传过来的时候可以不传参数或者字段
    price = serializers.CharField(write_only=True)

    #如果要取 出版社的city 之前跨表查询是 book.publish.city   现在 source = 'publish.city' 不需要点击本身这张表的字段了
    #   source的值传给了默认形参instance
    publish = serializers.CharField(source='publish.name')  #出版社名字

    #source不但可以指定一个字段,还可以指定一个方法  自定义choices字段取值固定用法get_字段_display
    book_type = serializers.CharField(source='get_category_display',read_only=True)

 

#model.py模型表
class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    category = 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 '方法'

 

   在视图中使用序列化的类

     实例化序列化的类产生对象,在产生对象的时候,传入需要序列化的对象(queryset)   

    对象.data    

     return Response(对象.data) 返回值用Response返回 

       如果序列化多条 many=True(也就是queryset对象,就需要写)  如果序列化一条(可以不写)instance是要序列化的对象

     

from app01.app01serializer import BookSerializer    #自定义的py文件下的序列化组件
from rest_framework.response import Response    #返回用的

class Books(APIView):
    def get(self,request):
        response = {'code':100,'msg':'查询成功'}
        books = models.Book.objects.all()
       
        bookser = BookSerializer(instance=books,many=True)
        # 如果序列化多条,many=True(也就是queryset对象,就需要写)
        print(bookser.data,type(bookser.data))
        response['data'] = bookser.data
        return Response(response)

    高级用法:SerializerMethodField搭配方法使用(get_字段名)  write_only 反序列化的时候该字段前端不显示  read_only 反序列化的时候前端可以不传这个字段

自定义py文件下的序列化组件 类下

from rest_framework import serializers  # 序列化组件
from app01 import models

class BookSerializer(serializers.Serializer):
    #序列化出版社的详情,指定SerializerMethodField之后,可以对应一个方法,返回什么内容,publish_detail就是什么内容
    publish_detail = serializers.SerializerMethodField(read_only=True)
    #对应的方法固定写法get_字段名
    def get_publish_detail(self,obj):   #这个obj 就是app01.models.Book
        print(obj,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()]

 

 

 

序列化的两种方式

 1 Serializers没有指定表模型

  source:指定要序列化那个字段,可以是字段,可以是方法

  SerializerMethodFields的用法

方式1:
authors = serializer.SerializerMethodField()
def get_authors(self,obj):
    return {'name':obj.publish.name,'city':obj.publish.city}
   #拓展性差  如果要查询一张表完整数据 那要写很多kv键值对

方式2:
class AuthorSerializer(serializer.Serializer):
    name = serializer.CharField()
    age = serializer.CharField()

authors = serializer.SerializerMethodField()
def get_authors(self,obj):
    ret = AuthorSerializer(instance=obj.authors.all(),man=True) #instance是默认参数可以不写
    return ret.data

 

 2 ModelSerializers:指定了表模型

  class Meta:  model=表模型  fields = ('__all__')显示所有的字段  fields = ('id','name')显示部分字段  exclude=['name'] 排除这个字段其他内容都显示 不能和fields同时使用  depth=1跨表深度是1,官方建议不要超过10,个人建议不要超过3  重写某个字段 在Meta外部,重写某些字段,方式同Serializers

 

class AuthorSerializer(serializers.Serializer):
    name = serializers.CharField()
    age = serializers.CharField()
    # class Meta:
        # fields = ('__all__')    serializers木有这个meta方法 只有modelserializer有

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book     #哪一张模型表
        # fields = ('nid','name') #显示的字段
        fields = ('__all__')    #显示所有字段信息
        # exclude = ['name']  #排除
        # depth=1
        # 深度是1,官方建议不要超过10,个人建议不要超过3
    category = serializers.CharField(source='get_category_display')
    authors = serializers.SerializerMethodField()
    def get_authors(self,obj):
        # 可以写列表生成式 如果是很多的话就要在生成式里面写很多   而且拓展性很差 可以继续写serializer
        ret=AuthorSerializer(instance=obj.authors.all(),many=True)
        return ret.data

    name5= serializers.CharField(source='name') #重写name字段 与meta同级别 方式和Serializers重写或者序列化组件一样

 

 

 

 

反序列化

 1 使用继承了Serializers序列化类的对象,反序列化  在自己写的序列化类中重写create方法,反序列化  重写create放法,实现序列化

  在序列化类中:  序列化类中写create方法表里面需要什么字段还是要传什么字段

from rest_framework import serializers  # 序列化组件
class BookSerializer(serializers.Serializer):
    #反序列化创建
    def create(self, validated_data):
        ret = models.Book.objects.create(**validated_data)
        return ret

  在视图中:

from app01.app01serializer import BookSerializer    #自定义py文件里为了和view视图函数隔离开 自定义文件就写serializer组件

class Books(APIView):
    #使用Serializers序列化类的对象,反序列化
    def post(self,request):
        #实例化产生一个序列化类的对象,data是要反序列化的字典
        bookser = BookSerializer(data=request.data)
        if bookser.is_valid():
            #清洗通过的数据
            ret = bookser.create(bookser.validated_data)
        return Response()

 

 

2 使用继承了ModelSerializers序列化类的对象,反序列化

  在视图中  在视图中写save() 表里面需要什么字段还是要传什么字段

from django.shortcuts import render,HttpResponse,redirect

from rest_framework.views import APIView
from app01 import models

from rest_framework.response import Response    #返回用的

# 把对象转成json格式字符串
from app01.app01serializer import BookSerializer    #自定义py文件里为了和view视图函数隔离开 自定义文件就写serializer组件

class Books(APIView):

    # 使用继承了ModelSerializers序列化类的对象,反序列化
    def post(self,request):
        #实例化产生一个序列化类的对象,data是要反序列的字典
        bookser = BookSerializer(data=request.data)
        if bookser.is_valid(raise_exception=True):  #抛出的异常前端可以看到
            #清洗通过的数据
            bookser.save()

 

 

反序列化的校验

反序列化的校验局部校验   validate_字段名(self,value):

  如果校验失败,抛出ValidationError(抛出的异常信息需要去视图层bookser.errors中取)

  如果校验通过直接return value

from rest_framework import exceptions

序列化类下面写:
    #反序列化的校验(局部校验,全局校验)
    def validate_name(self,value):

        print(value)
        raise exceptions.ValidationError('不能以sb开头')
        # if value.startswith('sb'):
        #     raise ValidationError('不能以sb开头')
        # return value
视图层 post请求内    校验错误信息
   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()

 

 

反序列化的校验全局  validate(self,attrs)  attrs所有校验通过的数据,是个字典  如果校验失败,抛出ValidationError  如果校验通过直接返回return attrs

序列化组件类中
    #去局校验
    def validate(self,attrs):
        print(attrs)

        return attrs

 

转载于:https://www.cnblogs.com/ZKPython/p/11124057.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值