• Djangorestframework之序列化组件


    Django自带序列化组件

    这是原生的django序列化组件 但是因为只能对所有的内容进行序列化 ,拓展性太差,所以我们基本启弃用

    from django.core import serializers
    def test(request):
        book_list = Book.objects.all()    
        ret = serializers.serialize("json", book_list)
        return HttpResponse(ret)

    drf序列化的两种方式

    第一种:  Serializers

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

    在视图中使用序列化的类
      1 实例化序列化的类产生对象,在产生对象的时候,传入需要序列化的对象(queryset)
      2 对象.data
      3 return Response(对象.data)
    高级用法:
      source:可以指定字段(name publish.name),可以指定方法,
      SerializerMethodField搭配方法使用(get_字段名字)
      publish_detail=serializers.SerializerMethodField(read_only=True)
      def get_publish_detail(self,obj):
      return {'name':obj.publish.name,'city':obj.publish.city}
      read_only:反序列化时,不传
      write_only:序列化时,不显示

    from rest_framework import serializers
    class AuthorSerializer(serializers.Serializer):
        name=serializers.CharField()
        age=serializers.CharField()
    class BookSerializer(serializers.Serializer):
    #     #指定source='name' ,表示序列化模型表中的name字段,重名命为name5(name和source='name'指定的name不能重名)
        name5=serializers.CharField(source='name')
    #     #write_only 序列化的时候,该字段不显示
    #     #read_only 反序列化的时候,该字段不传
        price=serializers.CharField(write_only=True)
    #     #如果要取 出版社的city source='publish.city'
        publish=serializers.CharField(source='publish.name')
    #     #source不但可以指定一个字段,还可以指定一个方法
    #     book_type = serializers.CharField(source='get_xx_display',read_only=True)
    #     #序列化出版社的详情,指定SerializerMethodField之后,可以对应一个方法,返回什么内容,publish_detail就是什么内容
        publish_detail=serializers.SerializerMethodField(read_only=True)
    #     #对应的方法固定写法get_字段名
        def get_publish_detail(self,obj):
            # print(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()]
            authorser=AuthorSerializer(obj.authors.all(),many=True)
            return authorser.data
    
        def create(self, validated_data):
            ret=models.Book.objects.create(**validated_data)
            return ret

    第二种: ModelSerialzers

    继承该类就指定了表模型
      class Meta:
      model=表模型
      1要显示的字段
      fields='__all__'
      fields=('id','name')(注释:列表元组均可以)
      2要排除的字段
      exclude=('name')
      3深度控制
      depth=1
      4重写某个字段
      在Meta外部,重写某些字段,方式同Serializers

    from rest_framework import serializers
    class AuthorSerializer(serializers.Serializer):
        name=serializers.CharField()
        age=serializers.CharField()
        
        
    from rest_framework import serializers
    from rest_framework import exceptions
    from rest_framework.exceptions import ValidationError
    from app01 import models
    
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model=models.Book
            # fields=('nid','name')
            #不能跟fields同时使用
            # exclude=['name',]
            fields=('__all__')
            #深度是1,官方建议不要超过10,个人建议不要超过3
            # depth=1
        xx=serializers.CharField(source='get_xx_display')
        authors=serializers.SerializerMethodField()
        def get_authors(self,obj):
            ret=AuthorSerializer(instance=obj.authors.all(),many=True)
            return ret.data
        name=serializers.CharField()
        #反序列化的校验(局部校验,全局校验)
        def validate_name(self,value):

    反序列化

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

    def create(self, validated_data):
    ret=models.Book.objects.create(**validated_data)
    return ret

    -在视图中:

    def post(self,request):
    bookser=BookSerializer(data=request.data)
    if bookser.is_valid():
    ret=bookser.create(bookser.validated_data)
    return Response()

    反序列化的校验

    validate_字段名(self,value):
      如果校验失败,抛出ValidationError(抛出的异常信息需要去bookser.errors中取)
      如果校验通过直接return value
    validate(self,attrs)
      attrs所有校验通过的数据,是个字典
      如果校验失败,抛出ValidationError
      如果校验通过直接return attrs

       def validate_name(self,value):
    
            print(value)
            # raise exceptions.ValidationError('不能以sb开头')
            if value.startswith('sb'):
                raise ValidationError('不能以sb开头')
            return value
    
        def validate(self,attrs):
            print(attrs)
            # if attrs.get('price')!=attrs.get('xx'):
            #     raise exceptions.ValidationError('name和price相等,不正常')
            return attrs
    承蒙关照
  • 相关阅读:
    [原]将Oracle 中的blob导出到文件中
    [原]unique index和non unique index的区别
    lsattr/chattr
    [原]说不清楚是Oracle的Bug还是TSM的Bug
    [摘]Oracle限制某个数据库帐号只能在特定机器上连入数据库
    [原]复制Oracle Home所需要注意的几个问题
    [原]Oracle Data Guard 折腾记(二)
    配置vsFTP的虚拟用户认证
    [原]给Oracle 11g Interval分区进行重命名
    [摘]如何抓住蝴蝶效应中的那只蝴蝶
  • 原文地址:https://www.cnblogs.com/guanlei/p/11123402.html
Copyright © 2020-2023  润新知