Django1.11序列化與反序列化

django序列化與反序列化

from rest_framwork import serializers

serializers.ModelSerializer

模型類序列化器,必須依據模型類建立序列化器

  • 基於模型類自動生成一系列字段
  • 包含默認的 crate()和update()前端

    定義ModelSerializer類

    定義序列化器
  • class BookInfoSerializer(serializer.ModelSerializer):
    class Meta:
    model = BookInfo
    filels = 'all'
    read_only_fields = ('id', 'readcount', 'commentcount')
    extra_kwargs = {
    'readcount': {'min_value': 0, 'required': True},
    'commentcount': {'max_value': 0, 'required': True},
    }
    • model,指明參照的那個模型類
    • fields ,指明爲模型類的那些字段生成
      • fields = ‘all’表示全部字段
      • exclude = ('iamge',) 表示排除哪些字段
      • fields = ('id','name','readcount') 表示顯示哪些字段
    • read_only_fields指明只讀字段,即僅用於序列化輸出的字段
    • extra_kwargs,爲ModelSerializer添加或修改原有的選型參數
      • extra_kwargs = {
        'readcount': {'min_value': 0, 'required': True},
        'commentcount': {'max_value': 0, 'required': True},
        }數據庫

        serailizers.Serializer

        便可覺得數據庫模型類定義,也能夠爲非數據庫模型類的數據定義

        定義Serializer類

        定義序列化器
  • class BookInfoSerializer(serializers.Serializers)
    id = serializers.IntegerField(label='ID', read_only=True)
  • 字段和選選項django

    建立Serializer對象

  • s = BookInfoSerializer(instance=None, data=empty, **kwarg)
    • instance:使用數據庫對象賦值,用於序列化
      data:字典類型數據,用於反序列化數據結構

      序列化

  • 將程序中的數據結構類型轉換爲其餘類型(字典,JSON,XML)Django中將模型類轉化爲JSON
  • 基本使用
    • 獲取須要序列化的對象
      • from book.models import BookInfo
        book = BookInfo.objects.get(id=4)
        • books = BookInfo.objects.all()
    • 構造序列化器對象
      • from book.serializers import BookInfoSerializer
        serializer = BookInfoSerializer(instance=book)
        • serializer = BookInfoSerializer(instace=books, many=True)
    • 獲取序列化數據
      • serializer.data
  • 關聯對象嵌套序列化
    • 若是須要序列化的數據中包含有其餘關聯對象,則對關聯對象數據的序列化須要指明
    • 關聯的對象數據是一個
      • PrimaryKeyRelatedFiled
        • class PeopleInfoSerializer(serializers.Serializer):
          #book = serializers.PrimaryKeyRelatedFiled(label='圖書',read_only=True)
          book = serializers.PrimaryKeyRelatedFiled(label='圖書',queryset=BookInfo.objects.all())
          • 包含read_only=True時,該字段不能用於反序列化使用
          • 包含queryset參數時,將被用做反序列化時參數校驗使用
        • 使用序列化器對象的data方法時
          對應字段顯示的是本表數據
          • {'id': 10, 'book': 3, 'description': '獨孤九劍', 'gender': 1, 'name': '令狐沖'}
      • StringRelatedFiledd
        • 此字段被序列化爲關聯對象的字符串表示方式(即__str__方法的返回值)
        • book = serializers.StringRelatedFiled(label='圖書')
          • class BookInfoSerializer(serializers.serializer):
            ...
            def str(self):
            return self.name
        • 使用序列化器對象的data方法時
          對應字段顯示的關聯表__str__方法返回的數據
          • {'description': '獨孤九劍', 'name': '令狐沖', 'gender': 1, 'book': '笑傲江湖', 'id': 10}
      • 使用關聯對象的序列化器
        • book = BookInfoSerializer()
        • 使用序列化器對象的data方法時
          對應字段顯示的式OrderDict對象=有序字典
          • {'book': OrderedDict([('id', 3), ('name', '笑傲江湖'), ('pub_date', '1995-12-24'), ('readcount', 28), ('commentcount', ('image', None)]), 'gender': 1, 'name': '令狐沖', 'description': '獨孤九劍', 'id': 10}
    • 關聯對象的數據是多個
      • many參數
      • 使用django建立模型類的時候,一對多的一表有peopleinfo_set隱藏字段
      • 若是關聯對象的數據不是隻有一個,而是包含多個數據,如想序列化對應數據時,此時關聯字段類型的指明仍使用上述方法,只是在聲明關聯字段時,多補充一個many=True參數便可
        • class BookInfoSerializer(serializers.Serializer):
          peopleinfo_set = serializers.PrimarykeyRelatedField(read_only=True,many=True)
  • from book.models import BookInfo
    from book.serializers import BookInfoSerializer
    book = BookInfo.objects.get(id=3)
    serializer = BookInfoSerializer(book)
    serializer.data
    {'id': 3, 'peopleinfo_set': [10, 11, 12, 13], 'commentcount': 18, 'name': '笑傲江湖', 'readcount': 28, 'pub_date': '199-24', 'image': None}ui

    反序列化

  • 與序列化相反,Django中將JSOn字符串轉化爲Django中的模型類對象
  • 驗證數據
    • from book.serializers import BookInfoSerializer
      data = {'pub_date':123}
      serializer = BookInfoSerializer(data=data)
      serializer.is_valid()
      False
      serializer.errors
      {'pub_date': [ErrorDetail(string='Date has wrong format. Use one of these formats instead: YYYY[-MM[-DD]].', code='invalid')], 'name': [ErrorDetail(string='This field is required.', code='required')]}
      serializer.validated_data
      {}rest

    • 使用序列化器進行反序列化時,須要對數據進行驗證後,才能獲取
      驗證成功的數據或保存成模型類對象
    • 序列化器對象調用is_valid()
      • 經過字段類型和選型驗證,驗證成功返回True,失敗返回False
      • is_valid(raise_exception=True)
        • 驗證失敗後拋出serializers.ValidationError
        • 向前端返回HTTP 400 Bad Request響應
      • 自定義驗證方法
        • validate_
          • 在序列化器中定義固定方法,驗證單一字段
            • class BookInfoSerializer(serializers.Serializer):
              """圖書數據序列化器"""
              id = serializers.IntegerField(label='ID', read_only=True)
              peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增
              def validate_readcount(self,value):
              if value < 0:
              raise serializers.ValidationError('閱讀數量不能爲負數')
              return value
        • validate
          • 在序列化器中定義固定方法,驗證多個字段
            • class BookInfoSerializer(serializers.Serializer):
              id = serializers.IntegerFiled(label='ID',read_only=True)
              readcount = serializers..IntegerFiled(label='閱讀量',required=False)
              commentcount = serializers..IntegerFiled(label='評論量',required=False)
              def validate(self,attrs):
              readcount = attrs.get('readcount')
              commentcount = attrs['commentcount']
              if commentcount > readcount:
              raise serializers.ValidationError('評論量不能大於閱讀量')
              returen attrs
        • validators
          • 在字段中添加validators選項參數,補充驗證行爲
            • class BookInfoSerializer(serializers.Serializer):

    def custom_validate(value):
    raise serializers.ValidationError('我就是來搗亂的')code

    """圖書數據序列化器"""
    id = serializers.IntegerField(label='ID', read_only=True)
    name = serializers.CharField(label='名稱', max_length=20,validators=[custom_validate])
    pub_date = serializers.DateField(label='發佈日期', required=False)
    readcount = serializers.IntegerField(label='閱讀量', required=False)
    commentcount = serializers.IntegerField(label='評論量', required=False)
    image = serializers.ImageField(label='圖片', required=False)
    peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增
    • 序列化器對象調用errors
      • 驗證失敗獲取錯誤信息
      • 驗證成功,獲取錯誤信息
    • 序列化器調用validated_data
      • 驗證成功獲取數據
  • 保存
    • 若是在驗證成功後,想要基於validated_data完成數據對象的建立,能夠經過實現create()和update()兩個方法來實現。
      • class BookInfoSerializer(serializers.Serializer):

    """圖書數據序列化器"""
    id = serializers.IntegerField(label='ID', read_only=True)
    name = serializers.CharField(label='名稱', max_length=20)
    pub_date = serializers.DateField(label='發佈日期', required=False)
    readcount = serializers.IntegerField(label='閱讀量', required=False)
    commentcount = serializers.IntegerField(label='評論量', required=False)
    image = serializers.ImageField(label='圖片', required=False)
    peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增orm

    def create(self, validated_data):
    """新建"""
    return BookInfo(**validated_data)對象

    def update(self, instance, validated_data):
    """更新,instance爲要更新的對象實例"""
    instance.name = validated_data.get('name', instance.name)
    instance.pub_date = validated_data.get('pub_date', instance.pub_date)
    instance.readcount = validated_data.get('readcount', instance.readcount)
    instance.commentcount = validated_data.get('commentcount', instance.commentcount)
    return instance
    • 若是須要在返回數據對象的時候,也將數據保存到數據庫中,則能夠進行以下修改
      • class BookInfoSerializer(serializers.Serializer):

    """圖書數據序列化器"""
    id = serializers.IntegerField(label='ID', read_only=True)
    name = serializers.CharField(label='名稱', max_length=20)
    pub_date = serializers.DateField(label='發佈日期', required=False)
    readcount = serializers.IntegerField(label='閱讀量', required=False)
    commentcount = serializers.IntegerField(label='評論量', required=False)
    image = serializers.ImageField(label='圖片', required=False)
    peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增blog

    def create(self, validated_data):
    """新建"""
    return BookInfo.objects.create(**validated_data)

    def update(self, instance, validated_data):
    """更新,instance爲要更新的對象實例"""
    instance.name = validated_data.get('name', instance.name)
    instance.pub_date = validated_data.get('pub_date', instance.pub_date)
    instance.readcount = validated_data.get('readcount', instance.readcount)
    instance.commentcount = validated_data.get('commentcount', instance.commentcount)
    instance.save()
    return instance
    • 實現了上述兩個方法後,在反序列化數據的時候,就能夠經過save()方法返回一個數據對象實例了
      • serializer.save()
      • 若是建立序列化器對象的時候,沒有傳遞instance實例,則調用save()方法的時候,create()被調用,相反,若是傳遞了instance實例,則調用save()方法的時候,update()被調用。

XMind: ZEN - Trial Version

相關文章
相關標籤/搜索