序列化组件

帅比萌擦擦* 提交于 2019-12-18 09:41:41

1,序列化

  1. 声明序列化器,具体代码如下
from rest_framework import serializers
from DrfDemo.models import Book

# -----------------------这是第一版get请求的serializers------------------
class PublisherSerializrs(serializers.Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField(max_length=32)


# 在类中写了字段,书写校验这个字段
class AuthorSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=32)


class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField(max_length=32)
    pub_time = serializers.DateField()
    category = serializers.CharField(source="get_category_display")
    # 关于外键的验证用外键字段名Serializers的方法
    publisher = PublisherSerializrs()
    authors = AuthorSerializer(many=True)
  1. 业务逻辑处理部分
序列化代码

2,反序列化,post请求

  1. 确定新增的数据结构
  2. 序列化器
    1. 正序和反序字段不统一
    2. required= False  只序列化,不走校验
    3. read_only=True 只序列化用
    4. write_only =True 只反序列化用
    5. 重写create方法
  3. 验证通过返回ser_obj.validated_data
  4. 验证不通过返回ser_obj.errors 

3,反序列化,put/patch请求

  1. 重写update方法
  2. ser_obj = Bookserializer(instance=obj, data=request.data, partial=True)
  3. 验证通过返回ser_obj.validated_data
  4. 验证不通过返回ser_obj.errors
正序,反序字段不统一

 4,验证

  1. 自定义的验证 权重111
    • def_my_validate(value):
      • 不通过抛异常:raise serializer.ValidationError("错误信息")
      • 通过return value
      • 配置----->给字段加validations=[My_validate]
  1. 单个字段的验证 权重222
    • def validate_字段名称(self, value):
      • 不通过raise serializers.ValidationErrors("错误信息")
  1. 多个字段的验证 权重333
    • def validate(self, attrs):
      • attrs是所有字段组成的字典
      • 不通过raise serializers.ValidationError("错误信息")
校验器
from rest_framework.views import APIView
from rest_framework.response import Response
from DrfDemo.models import Book
from DrfDemo.serializers import BookSerializer


class BookView(APIView):
    # 定义一个get请求的额度方法
    def get(self, request):
        # 从数据库中获取数据
        book_queryset = Book.objects.all()
        print()
        # 用序列化器进行序列化
        ser_obj = BookSerializer(book_queryset, many=True)
        # 既然用rest_frame框架就用人家提供的response
        return Response(ser_obj.data)

    # 手写一个post获取数据的方法(新增)
    def post(self, request):
        # 1,确定数据类型以及数据结构
        # 2,对前端妹子传过来的的数据进行校验
        book_obj = request.data  # 获取前端传过来的数据
        print("前端传过来的数据:", book_obj, type(book_obj))
        # 把获取到的数传给BookSerializer方法里进行校验
        ser_obj = BookSerializer(data=book_obj)
        # 如果通过校验
        if ser_obj.is_valid():
            print("通过校验的数据:", ser_obj)
            # 把通过校验的更新到数据库中
            ser_obj.save()
            print(456)
            # 更新完以后把更新后的数据展示到前端
            return Response(ser_obj.validated_data)
        # 如果没通过校验就返回错误信息,错误信息都封装在了ser_obj中
        return Response(ser_obj.errors)


# 编辑CBV
class BookEditView(APIView):
    # 手写一个get请求
    def get(self, request, id):
        # 获取到要更新数据的对象
        book_obj = Book.objects.filter(id=id).first()
        ser_obj = BookSerializer(book_obj)  # 单个对象的时候不用many=True
        # 返回这个数据经过序列化的数据
        return Response(ser_obj.data)

    # 手写一个put更新的方法
    def put(self, request, id):
        book_obj = Book.objects.filter(id=id).first()
        # 把筛选到的对象去调用BookSerializer方法
        ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True)
        print(ser_obj)
        if ser_obj.is_valid():
            ser_obj.save()
            print(123)
            # 返回经过更新到数据库的数据
            return Response(ser_obj.validated_data)
        # 否则报错误
        return Response(ser_obj.errors)

序列化代码

5,序列化器的ModelSerializer

  1. 定义一个序列化器继承(serializers.ModelSerializer)
  2. 源信息的配置
    1. class Meta
    2. fileds = "__all__"
    3. exclude = ["字段名",]
    4. depth = 1       (depth会让所有的外键关系字段都变成read_only = True)
    5. extra_kwargs= {"默认的字段名称":{自定义的参数配置信息}}
    6. SerializerMethodField()方法字段
      • def get_字段名称(self, obj):
        • obj 每次序列化的模型对象
        • return 自定义的数据
ModelSerializer
def my_validate(value):
    print(value)
    if "雪雪" in value.lower():
        raise serializers.ValidationError("这太暴露了")
    return value

class PublisherSerializrs(serializers.Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField(max_length=32)


# 在类中写了字段,书写校验这个字段
class AuthorSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=32)


# 重新写Book的序列化器
class BookSerializer(serializers.Serializer):
    # 1,不是进行必须的序列化和反序列化
    id = serializers.IntegerField(required=False)  # 表示不是必须进行序列化
    # 2,默认的字段,不管是序列化,还是反序列化都需要通过这几个字段
    title = serializers.CharField(max_length=32, validators=[my_validate])
    pub_time = serializers.DateField()
    # 3,序列化要走的字段
    category = serializers.CharField(source="get_category_display", read_only=True)
    publisher = PublisherSerializrs(read_only=True)
    authors = AuthorSerializer(many=True, read_only=True)  # 多对多要用many=True
    # 4,反序列化要走的字段
    # 反序列化提交的数据都是自定义的不是字段名(注意自定的数据这的字段名和提交数据一致,否则报错)
    post_category = serializers.IntegerField(write_only=True)
    publisher_id = serializers.IntegerField(write_only=True)
    author_list = serializers.ListField(write_only=True)

    # 1,提交数据的时候要重写create方法(增加的时候)
    def create(self, validated_data):
        # validated_data 校验通过的数据就是book_obj,通过ORM操作给Boook表增加数据
        print("在view中通过校验的数据:",validated_data)
        book_obj = Book.objects.create(
            title=validated_data["title"],
            pub_time=validated_data["pub_time"],
            category=validated_data["post_category"],
            publisher_id=validated_data["publisher_id"]
        )
        print("serializers中的book_obj", book_obj)
        # 需要把这个对象的多对多的数据创建出来
        book_obj.authors.add(*validated_data["author_list"])
        # 把值存在于ORM的操作更新到数据库中
        # book_obj.save()
        print(123)
        return book_obj

    # 2,更新数据的方法
    def update(self, instance, validated_data):
        # 参数说明:instance是要更新的book_obj对象, validated_data是通过校验的数据
        #  接下来就是ORM操作, 把要所有哦的字段都要写一遍
        instance.title = validated_data.get("title", instance.title)
        instance.pub_time = validated_data.get("pub_time", instance.pub_time)
        instance.category = validated_data.get("post_category", instance.category)
        instance.publisher_id = validated_data.get("publisher_id", instance.publisher_id)
        # 对于多对多的的外键需要判断存不存在author_list
        if validated_data.get("author_list"):
            # 用set设置的时候不用拍散,它会自动一个一个的去设置
            instance.authors.set(validated_data["author_list"])
        print(instance)
        # instance.save()
        print(456)
        return instance

    # 局部校验方法
    def validate_title(self, value):
        if "小雪" not in value.lower():
            raise serializers.ValidationError("不符合社会主义核心价值观")
        return value

    # 全局的校验方法
    def validate(self, attrs):
        if attrs["post_category"] == 1:
            return attrs
        else:
            raise serializers.ValidationError("1,难道不好吗?")

正序,反序字段不统一

小结:

  1. 先去cmd中下载rest_framework框架: pip install djangorestframework
  2. 在settings的app中注册rest_framework
  3. app里创建一个py文件导入rest_framework: from rest_framework import serializers
  4. 创建类继承serializers.Serializer
  5. 把表中的需要匹配的字段写在类中,注意many=True, 前端显示source="get_字段_display"

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!