序列化组件

介绍

# 作用:
1. 序列化,序列化器(类)会把模型对象(Book对象,Queryset对象)转换成字典,经过response以后变成json字符串
2. 反序列化,把客户端发送过来的数据,经过request以后变成字典(request.data),序列化器(类)可以把字典转成模型
3. 反序列化,完成数据校验功能

# Django REST framework中的Serializer使用类来定义,须继rest_framework.serializers.Serializer

使用

序列化类
from rest_framework import serializers
from .models import Books
class BookSerializer(serializers.Serializer):
    #写字段(要序列化,反序列化的字段)
    name=serializers.CharField()
    price=serializers.IntegerField()
    publish=serializers.CharField()

    # 如果要更新,一定要重写update方法
    def update(self, instance, validated_data):
        # 修改
        instance.name=validated_data.get('name')
        instance.price=validated_data.get('price')
        instance.publish=validated_data.get('publish')
        # 保存
        instance.save()
        # 返回
        return instance


    # 如果要新增,一定要重写create方法
    def create(self, validated_data):
        # 保存
        book=Books.objects.create(**validated_data)
        # 一定记得return
        return book
    
视图类
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Books
from rest_framework.request import Request
from .serizlizer import BookSerializer
class BookAPIView(APIView):
    #查询所有接口
    def get(self, request, *args, **kwargs):

        book_list=Books.objects.all()
        # 序列化过程,把queryset转成字典
        # 第一个参数是要序列化的对象,如果序列化多条数据,一定要加上many=True
        ser=BookSerializer(instance=book_list,many=True)
        print(ser.data)
        return Response(ser.data)


    def post(self, request, *args, **kwargs):

        ser=BookSerializer(data=request.data) #新增,不用传instance
        if ser.is_valid():
            ser.save()
            return Response(ser.data)

# 查询单个接口
class BookDetailAPIView(APIView):
    # 查询单个
    def get(self, request, pk):

        book = Books.objects.filter(pk=pk).first()
        # 序列化过程,把Book转成字典
        # 第一个参数是要序列化的对象,如果序列化多条数据
        ser = BookSerializer(instance=book)
        print(ser.data)
        return Response(ser.data)


    def delete(self,request,pk):
        Books.objects.filter(pk=pk).delete()
        return Response()

    def put(self,request,pk):

        book=Books.objects.filter(pk=pk).first()
        # 反序列化,修改
        # instance 传要修改的对象
        ser=BookSerializer(instance=book,data=request.data)  #修改
        # 校验数据
        if ser.is_valid():
            ser.save() # 报错
            return Response(ser.data)

反序列化

数据验证

使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象。

在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False。

验证失败,可以通过序列化器对象的errors属性获取错误信息,返回字典,包含了字段和字段的错误。如果是非字段错误,可以通过修改REST framework配置中的NON_FIELD_ERRORS_KEY来控制错误字典中的键名。

验证成功,可以通过序列化器对象的validated_data属性获取数据。

在定义序列化器时,指明每个字段的序列化类型和选项参数,本身就是一种验证行为。

Serializer高级使用

1. source 字段的作用
	-book_name=serializers.CharField(source="name")
    -source 可以对应表模型的字段和方法(返回结果是什么,字段就是什么),表模型中写的方法
    -一般用来做一对多,多对多的字段返回
    
2. SerializerMethodField
	-使用方法如下
     publish=serializers.SerializerMethodField()
     def get_publish(self,obj):
        return {'name':obj.publish.name,'addr':obj.publish.addr}
    
3. 字段自己的校验规则
	-name=serializers.CharField(max_length=8,min_length=3)
4. 局部钩子
	def validate_name(self,name):
        if name.startswith('sb'):
            raise ValidationError('不能以sb开头')
        else:
            return name

5. 全局钩子
	   def validate(self, attrs):
            name=attrs.get('name')
            print(name)
            addr=attrs.get('addr')
            print(addr)
            return attrs

模型类序列化器

如果我们想要使用序列化器对应的是Django的模型类,DRF为我们提供了ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类。

ModelSerializer与常规的Serializer相同,但提供了:

  • 基于模型类自动生成一系列字段
  • 基于模型类自动为Serializer生成validators,比如unique_together
  • 包含默认的create()和update()的实现
1 继承ModelSerializer
	-class PublishModelSerializer(serializers.ModelSerializer):
2 字段是通过表模型映射过来的
	class Meta:
        model=Publish  #表模型
        fields='__all__' # 序列化的字段
        # exclude=['id','name'] #排除的字段
        # depth    # 深度,一般不用
3 可以重写字段
	name = serializers.SerializerMethodField()
    def get_name(self, obj):
         return '著名出版社:' + obj.name
        
4 可以扩写字段(表模型中没有的字段)

5 反序列化时,字段自己的校验规则,映射了表模型的
6 局部钩子和全局钩子完全一样



7 wirte_only和read_only
    # 反序列化时候使用,  序列化时候不用
    # name=serializers.CharField(write_only=True)

    # 序列化的时候使用,反序列化不用
    # name=serializers.CharField(read_only=True)
    
8 extra_kwargs
		# 额外给字段传递参数,类似于
        # name = serializers.CharField(write_only=True,'max_length':8)
        extra_kwargs={'name':{'write_only':True,'max_length':8}}