DRF序列化和反序列化

一、自定义序列化组件

  • 新建一个任意名的py文件,里面导入serlizer
from rest_framework import serializers
自定义一个类继承serializers,里面写需要序列化的字段
  1. 方法一:继承serializers.Serializer
class BookSerlizer(serializers.Serializer):
    title = serializers.CharField()
    price = serializers.IntegerField()
    pub_date = serializers.DateField()
	# source 可以指定一个字段也可以指定一个方法
    publish = serializers.CharField(source='publish.name')
	# 获取作者所有的信息,指定SerializerMethodField之后,可以对应一个方法,返回什么内容,authors就是什么内容
    authors = serializers.SerializerMethodField(read_only=True)
	#  对应的方法固定写法get_字段名
    def get_authors(self, obj):
        author_ser = AuthorSerlizer(obj.authors.all(), many=True)
        return author_ser.data
方法二:继承serializers.ModelSerializer
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model=models.Book
        # fields=('nid','name')
        #不能跟fields同时使用
        # exclude=['name',]
        fields=('__all__')
        #深度是1,官方建议不要超过10,个人建议不要超过3
        # depth=1

    authors=serializers.SerializerMethodField()
    def get_authors(self,obj):
        ret=AuthorSerializer(instance=obj.authors.all(),many=True)
        return ret.data
    name=serializers.CharField()
  • 视图层
class Books(APIView):
    def get(self, request):
        back_dic = {
            'code': 100,
            'msg': '查询成功',
        }
        # 获取所有的图书数据
        books = models.Book.objects.all()
        # print(books)
        # 序列化数据,many为True序列化多条数据,false序列化一条数据
        # instance 序列化,data 反序列化
        book_ser = BookSerlizer(instance=books, many=True)
        # print(book_ser)
        # 获取序列化后的数据
        back_dic['data'] = book_ser.data
        print(back_dic)
        return Response(back_dic)

二、高级用法

1.source 的用法

  • 可以指向字段
from rest_framework import serializers


class BookSerializer(serializers.Serializer):
    book_name = serializers.CharField(source='book')
    price = serializers.CharField()
	# 指向字段名
    publish = serializers.CharField(source='publish.name')
可以指定方法
class BookSerializer(serializers.ModelSerializer):
	# 指向方法
    book_type =serializers.CharField(source='get_xx_display',read_only=True)

三、序列化总结

-序列化的两种方式
-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

四、反序列化

1、使用继承了Serializers序列化类的对象

  • 序列化生成器中:自己重写create方法保存数据
def create(self, validated_data):
        # print('1',validated_data)
        publish = validated_data.pop('publish')

        publish_obj = models.Publish.objects.filter(name=publish['name']).first()
        # print(publish_obj)
        validated_data['publish'] = publish_obj
        res = models.Book.objects.create(**validated_data)

        return res
视图层
def post(self, request):
        back_dic = {
            'code': 100,
            'msg': '',
        }

        # 反序列化传入data
        book_ser = BookSerlizer(data=request.data)
        # print('1',request.data)
        # 校验数是否合法
        print(book_ser.is_valid())
        # print(book_ser.errors)
        if book_ser.is_valid():
            print(book_ser.validated_data)
            book_ser.create(book_ser.validated_data)

            back_dic['data'] = book_ser.validated_data
            back_dic['msg'] = '新增成功'
            # print(back_dic)
        return Response(back_dic)

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

  • 序列化生成器中不需要修改
  • 视图函数中直接调用save方法
def post(self,request):
    bookser=BookSerializer(data=request.data)
    if bookser.is_valid():
    ret=bookser.save()
    return Response()

五、反序列化的校验——钩子函数

  • 局部钩子
   def validate_name(self,value):

        print(value)

        if value.startswith('sb'):
            raise exceptions.ValidationError('不能以sb开头')
        return value
全局钩子
    def validate(self,attrs):
        print(attrs)
        if attrs.get('price')!=attrs.get('xx'):
            raise exceptions.ValidationError('name和price相等,不正常')
        return attrs
反序列化的校验
        -validate_字段名(self,value):
            -如果校验失败,抛出ValidationError(抛出的异常信息需要去bookser.errors中取)
            -如果校验通过直接return value
        -validate(self,attrs)
            -attrs所有校验通过的数据,是个字典
            -如果校验失败,抛出ValidationError
            -如果校验通过直接return attrs

转载于:https://www.cnblogs.com/king-home/p/11126427.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值