1. 程式人生 > >Django:(08)序列化器

Django:(08)序列化器

1、序列化和反序列化
變數從記憶體中變成可儲存或傳輸的過程稱之為序列化,序列化之後,就可以把序列化後的內容寫入磁碟,或者通過網路傳輸到別的機器上。
反過來,把變數內容從序列化的物件重新讀到記憶體裡稱之為反序列化。

序列化是將物件狀態轉換為可保持或可傳輸的形式的過程。序列化的補集是反序列化,後者將流轉換為物件。這兩個過程一起保證資料易於儲存和傳輸。

2、Django中序列化器的定義和使用
定義:兩種方法定義序列化器(serializer/ModelSerializer)

class CartSKUSerializer(serializers.ModelSerializer):
    """
購物車商品資料序列化器 """ count = serializers.IntegerField(label='數量') class Meta: model = SKU fields = ('id', 'name', 'default_image_url', 'price', 'count')

 

使用:
  查詢模型類
  例項一個序列化器,傳入模型類物件
  獲取序列化後的結果(data屬性)

query_set = Department.objects.all()
serializer = DepartmentSerializer(query_set, many=True)#
傳入物件集時需指定many=True serializer.data

 

3、Django中反序列化的引數校驗
基本校驗:
  序列化器的建立: 通過data傳入字典資料:

Serializer(instance=None, data=empty, **kwarg)

 

  通過is_valid方法校驗引數合法性
  errors屬性: 獲取校驗出錯資訊,字典型別。
  validated_data屬性: 校驗通過得到的物件,型別為OrderedDict
通過 validators選項校驗
  在序列化器欄位中新增validators選項引數進行校驗
  定義函式:

def validate_name(value):
    # 校驗部門名稱
    if not re.match('^[\u4e00-\u9fa5]+$', value):
        raise ValidationError('部門名稱只能為中文')
    return value

  在欄位引數中新增選項:validators=[validate_name]

name = serializers.CharField(validators=[validate_name])

 

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

    class DepartmentSerializer(serializers.Serializer):
    """部門資料序列化器"""
    ...
    def validate_name(self, value):
        # 校驗部門名稱
        if not re.match('^[\u4e00-\u9fa5]+$', value):
            raise ValidationError('部門名稱只能為中文')
        return value

 

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

     # 模型: users/models.py
 class User(models.Model):
     password = models.CharField(max_length=30)

 # 序列化器: users/serializer.py
 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):
         # 校驗兩次輸入的密碼是否正確
         password = attrs['password']
         password2 = attrs['password2']
         if password != password2:
             raise serializers.ValidationError('兩次輸入的密碼不一樣')
         return attrs

 

3、Django中反序列化儲存和修改資料

  1. Serializer類的三個方法

    • save()方法: 儲存資料
    • create()方法: 新增資料
    • update()方法: 修改資料
  2. 新增或修改資料

    Serializer(instance=None, data=empty)

     

    1. 新增:建立序列化器時,沒有傳遞了instance引數

       my_dict = {'name': '研發部xx', 'create_date': '2018-1-1'}
       s = DepartmentSerializer(data=my_dict)    
       s.save()        # 新增

       

    2. 修改:建立序列化器時,傳遞了instance引數

      department = Department.objects.get(id=1)
       my_dict = {'name': '研發部xx', 'create_date': '2018-1-1'}
       s = DepartmentSerializer(instance=department, data=my_dict)    
       s.save()        # 修改

       

    3. 部分修改:partial=True 引數

      1. 當修改資料時,序列化器預設要求傳遞所有required=True的欄位,否則is_valid驗證不通過
      2. 可以通過設定partial=True允許只修改部分欄位,如下:

s = DepartmentSerializer(department, data={'create_date': '2017-1-1'}, partial=True)

4、模型類序列化器

定義
  model 指明參照哪個模型類
  fields 指定序列化器中的屬性有哪些 (可以是模型類中的欄位,也可以模型類中沒有的但需要校驗的屬性,比如類似:簡訊驗證碼,確認密碼)

class DepartmentSerializer2(serializers.ModelSerializer):
    class Meta:
        model = Department 
        fields = '__all__' # 包含模型類中所有的欄位

指定序列化器中包含哪些欄位:fields = ('id', 'name')
排除掉模型類中指定的欄位:exclude = ('is_delete',)
指明只讀欄位
  read_only_fields = ('id', 'create_date')
  僅用於序列化輸出,在反序列化時不會進行校驗和修改
指定 關聯屬性的序列化方式