1. 程式人生 > >序列化器反序列化的使用

序列化器反序列化的使用

  • 反序列化原理:

Json字串-->字典-->物件

  • 反序列化的作用:

1.校驗引數的準確性

2.校驗通過後,可以在資料庫中儲存或修改資料

  • 反序列化的使用:

首先定義序列化器:

class DepartmentSerializer(serializers.Serializer):
    """部門序列化器類"""
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField(max_length=20)
    create_date 
= serializers.DateField() is_delete = serializers.BooleanField(default=False)

 

功能一:校驗引數的準確性

當我們想把一個字典轉換為物件儲存到資料庫時,往往需要先校驗其引數的準確性,有沒有符合欄位的約束。

from [app資料夾].models import *
from [app資料夾].serializers import *
# 定義一個要儲存到資料庫的字典
data_dict = {"name":"網路部","create_time":"2011-1-1"}
# 校驗引數
a = DepartmentSerializer(data=data_dict)
# 校驗引數是否合法,校驗通過返回True,否則返回False a.is_vaild() # 如果不通過,可以看錯誤在哪 a.errors # 獲取字典裡能通過的鍵值對(不通過的時候是{}) a.validated_data

補充:is_valid()可以丟擲異常,寫法:is_valid(raise_exception=True)。當然,拋了異常後下面的程式碼就不會執行了。

 

如果預設的欄位型別和選項不能滿足校驗的需求,可以自定義補充校驗

(1)通過validators選項進行校驗

# 函式的名字和接受的引數名都可以隨便寫
def jiaoyan(value):
    
if not re.match('^[\u4e00-\u9fa5]+$',value): # 異常名稱是固定的! raise ValidationError("部門只能為中文") return value class DepartmentSerializer(serializers.Serializer): """部門序列化器類""" id = serializers.IntegerField(read_only=True) # validators指定校驗器的名稱 name = serializers.CharField(max_length=20,validators=[jiaoyan]) create_date = serializers.DateField() is_delete = serializers.BooleanField(default=False)

(2)validate_<field>:對<field_name>欄位進行驗證

class DepartmentSerializer(serializers.Serializer):
    """部門序列化器類"""
    id = serializers.IntegerField(read_only=True)
    # validators指定校驗器的名稱
    name = serializers.CharField(max_length=20)
    create_date = serializers.DateField()
    is_delete = serializers.BooleanField(default=False)

    # 函式的名字是固定的,validate_加上要校驗的欄位名
    def validate_name(self,value):
        if not re.match('^[\u4e00-\u9fa5]+$', value):
            # 異常名稱是固定的!
            raise ValidationError("部門只能為中文")
        return value

(3)validate:同時對多個欄位進行比較驗證

例如,註冊時驗證使用者輸入的兩個密碼是否一致:

class UserSerializer(serializers.Serializer):

     password = serializers.CharField(max_length=30, write_only=True)
     password2 = serializers.CharField(max_length=30, write_only=True)
     # 函式名是固定的!
     def validate(self, attrs):
         # 新增使用者時客戶端傳遞請求引數:
         # {"name":"Jack",  "password": "123456", "password2":"123456"}
         # attrs這個名字可以隨便寫,代表著整個字典
         password = attrs['password']
         password2 = attrs['password2']
         if password != password2:
             # 異常名稱固定!
             raise ValidationError('兩次輸入的密碼不一樣')
         return attrs

 

 

功能二:把校驗通過的字典轉換為物件,新增或修改

1.重寫序列器類的create函式(新增)和update函式(修改)

class DepartmentSerializer(serializers.Serializer):
    """部門序列化器類"""
    id = serializers.IntegerField(read_only=True)
    name = serializers.CharField(max_length=20)
    create_date = serializers.DateField()
    is_delete = serializers.BooleanField(default=False)

    def create(self, validated_data):
        # validated_data是校驗通過的有序字典
        # 方式一,增加資料
        dep = Department.objects.create(name=validated_data.get("name"),create_date=validated_data.get("create_date"))
        # 方式二,增加資料
        dep = Department.objects.create(**validated_data)
        return dep

    def update(self, instance, validated_data):
        # instance表示的是待修改的物件,需要先查詢出來。
     # validated_data是校驗通過的字典
     # get後面設定預設值,是為了防止沒有修改該欄位時,沒有接收到值,從而給物件原本的值設定為空
instance.name = validated_data.get("name",instance.name) instance.create_date = validated_data.get("create_date",instance.create_date) instance.save() return instance

 

2.使用

from user.serializers import *
from user.models import *

# 新增操作
a = DepartmentSerializer(instance=dep,data={"name":"英語角","create_date":"2001-1-1"})
a.save()

# 修改操作
dep = Department.objects.get(id=6)
a = DepartmentSerializer(instance=dep,data={"name":"英語角","create_date":"2001-1-1"})
a.save()

注意:當只修改部分欄位時,可以通過設定partial=True允許只修改部分欄位。示例:

dep = Department.objects.get(id=8)
s = DepartmentSerializer(dep, data={'create_date': '2017-1-1'}, partial=True)
s.is_valid()
s.save()