DRF序列化/反序列化

反序列化(不推荐版):
两个字段 一个为正序准备,一个为反序准备
重写create update方法

1. 确定数据结构: 自己定义key
   book_obj = {
       "title": "语文sadasd",
       "pub_time": "2018-11-14",
       "post_category": 2,
       "publisher_id": 1,
       "authors_list": [1, 2]
}

2. 序列化器: 注意外键,多对多,多选需要反序列化,其余不用
   正序和反序列化字段不统一: 

   1. 注意id 只序列化不走校验(required=False)
      id = serializers.IntegerField(required=False)

   2. 注意选择 
      # 正序用
      category = serializers.CharField(source="get_category_display", read_only=True)
      # 只能反序用 新增分类
      post_category = serializers.IntegerField(write_only=True)

   3. 注意外键
      publisher = PublisherSerializer(read_only=True)
      publisher_id = serializers.IntegerField(write_only=True)

   4. 注意多对多
      authors = AuthorSerializer(many=True, read_only=True)
      authors_list = serializers.ListField(write_only=True)

   4. 重写create方法
      def create(self, 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"])
          book_obj.authors.add(*validated_data["authors_list"])
          return book_obj
   
3. 验证通过返回ser_obj.validated_data
4. 验证不通过返回ser_obj.errors

字段校验: 权重: 自定义>单个>多个

# 自定义验证函数,需要加在类的前面, 然后哪个字段需要校验,哪个字段中添加 validators=[my_validate]
    def my_validate(value):
        if "敏感信息" in value.lower():
            raise serializers.ValidationError("❌有敏感词汇")
        return value

    # 单个字段校验
    def validate_title(self,value):
        # value就是title的值,对value处理
        if "python" not in value.lower():
                raise serializers.ValidationError("标题必须含有python")
        return value

    # 多个字段校验
    def validate(self, attrs):
        # attrs 字段有全部传过来的所有字段
        if "xxx" in attrs['title'].lower() or attrs['post_category']==1:
            raise serializers.ValidationError('出错了')
        return attrs

ModelSerializer:

关联哪个字段,获取到哪个字段的全部信息
外键关系还是k为数字
需要重写正序字段

class BookSerializer(serializers.ModelSerializer):
    # 自定制 重写字段 需要重写正序,反序用默认
    category_display = serializers.SerializerMethodField(read_only=True)
    publisher_info = serializers.SerializerMethodField(read_only=True)
    authors_info = serializers.SerializerMethodField(read_only=True)

    # 钩子函数显示外键信息 obj:每次序列化的模型对象
    def get_category_display(self, obj):
        # obj是序列化的每个Book对象
        return obj.get_category_display() # 自定义要返回的内容

    def get_publisher_info(self, obj):
        publisher_obj = obj.publisher
        return {'id': publisher_obj.id, 'title': publisher_obj.title}

    def get_authors_info(self, obj):
        authors_queryset = obj.authors.all()
        return [{"id": author.id, "name": author.name} for author in authors_queryset]

    class Meta:
        model = Book 表名字
        fields = '__all__'
        # depth = 1 # 所有字段都拿出来一般不用, 会让所有的外间关系变成read_only = Trur
extra_kwargs = {
            'publisher': {'write_only': True},
            'authors': {'write_only': True},
        }
       # extra_kwargs={"默认的字段名称":{自定义的参数配置信息}}

猜你喜欢

转载自www.cnblogs.com/niuli1987/p/9966214.html