序列化與反序列化基礎

序列化與反序列化基礎

序列化 => 後臺數據到前臺,反序列化 => 前臺數據寫到後臺數據庫

一、內部類

一、概念

將類定義在一個類的內部,被定義的類就是內部類json

二、特色

內部類及內部類的名稱空間,能夠直接被外部類訪問網絡

三、應用

經過內部類的名稱空間,給外部類額外拓展一些特殊的屬性(配置),典型的Meta內部類 - 配置類app

class Book(model.Model):
    class Meta:
        db_model = "owen_book"  # 配置自定義表名
        
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = "Book"  # 配置序列化類綁定的Model表

二、DRF響應類:Response

drf的響應類Response內部屬性有:post

class Response(SimpleTemplateResponse):
    def __init__(self, data=None, status=None,
                 template_name=None, headers=None,
                 exception=False, content_type=None):

data:響應的數據 - 空、字符串、數字、列表、字典、布爾ui

status:網絡狀態碼spa

template_name:drf本身也能夠支持先後臺不分離的返回頁面,可是不能和data共存(不會涉及到)rest

headers:響應頭code

exception:是否有異常響應(若是異常能夠賦值爲True,沒什麼用)對象

content_type:響應的結果類型(響應式data默認是application/json)

常見響應:

from rest_framework import status
# 正常響應
Response(
    data={
        'status': 0,
        'msg': 'ok',
        'result': '正常數據'
    }
)
# 異常響應
Response(
    data={
        'status': 1,
        'msg': '客戶端錯誤提示',
    },
    status=status.HTTP_400_BAD_REQUEST,
    exception=True
)

三、序列化基類控制的初始化參數

序列化serializers類繼承的BaseSerializer類中初始化參數有如下的:

def __init__(self, instance=None, data=empty, **kwargs):
    pass

instance:是要被賦值對象的, - 對象類型數據賦值給instance

data:是被賦值數據的,- 請求來的數據賦值給data

kwargs:內部有三個屬性:many、partial、context

  • many:操做的對象或數據是單個或多個

  • partial:在修改需求時使用,能夠將全部的校驗字段required校驗規則設置爲False

  • context:用於視圖類和序列化類直接傳參使用

常見使用:

# 單查接口
UserModelSerializer(instance = user_obj)
​
# 羣查接口
UserModelSerializer(instance = user_query, many=True)
​
# 增接口
UserModelSerializer(data = request.data)
​
# 總體改接口
UserModelSerializer(instance = user_obj, data = request.data)
​
UserModelSerializer(instance = user_obj, data = requset.data, partial = True)
​
# 刪接口用不到序列化類

四、反序列化

views.py

class UserAPIView(APIView):
    def post(self, request, *args, **kwargs):
        # 單增
        # 1)將前臺請求的數據交給序列化類處理
        # 2)序列化類執行校驗方法,對前臺提交的全部數據進行數據校驗:校驗失敗就是異常返回,成功才能繼續
        # 3)序列化組件完成數據入庫操做,獲得入庫對象
        # 4)響應結果給前臺
        serializer = serializers.UserModelSerializer(data=request.data)
        if serializer.is_valid():  # is_valid校驗
            # 校驗成功 => 入庫 => 正常響應
            obj = serializer.save()  # save內部入庫
            return Response({
                'status': 0,
                'msg': 'ok',
                'result': serializers.UserModelSerializer(obj).data  # 新增的值返回
            }, status=status.HTTP_201_CREATED)
        else:
            # 校驗失敗 => 異常響應
            return Response({
                'status': 1,
                'msg': serializer.errors,  # errors錯誤信息
            }, status=status.HTTP_400_BAD_REQUEST)

serializers.py

開發流程:

  1. 在models類中自定義字段,在serializer類中自定義寫字段

  2. 將models自帶的字段和全部在model和serializer自定義的字段寫在fields中,用write_only和read_only區別

  3. 能夠在extra_kwargs中寫基礎的校驗規則,也能夠省略

  4. 制定局部鉤子與全局鉤子,全局鉤子在上述全部校驗後再校驗

一、不論是序列化仍是反序列化字段,都必須在field中進行聲明,沒有聲明的不會參與任何過程(數據會被丟棄)

二、用read_only 表示只讀,用write_only表示只寫,不標註二者默認表明便可讀也可寫

三、models類中的自定義的字段@property聲明的默認就是隻讀read_only

@property
def gender(self):
    return self.get_sex_display()

四、自定義的只寫字段,在serializer類中須要本身手動聲明write_only,serializer中自定義的字段必須明確write_only不然會報錯,由於序列化會從model中強行反射自定義的字段,而model中沒有該字段就會報錯,而對於model中已經有的字段,在serializer類中再次聲明會對model原有的字段進行覆蓋,能夠不明確write_only表示可讀可寫,而且要寫在Meta上方同級的

re_password = serializers.CharField(write_only=True)

五、用extra_kwargs來爲寫的字段制定基礎校驗規則,能夠在extra_kwargs中使用required表明是否必須參與寫操做,有默認值和能夠爲空的時該值爲False,反之爲True,能夠手動修改

# 制定簡易基礎校驗規則查看有哪些規則
# serializers.DecimalField.max_value
# serializers.CharField.max_length
        extra_kwargs = {
            'name': {
                'required': True,
                'max_length': 32,
                'error_messages': {  # 能夠被國際化配置替代
                    'max_length': '太長'
                }
            }
        }

六、每個字段咱們均可以自定義校驗規則,使用局部鉤子 validate_字段名(self, value) 方法來自定義校驗規則,成功在返回value,失敗在拋出exceptions.ValidationError('異常信息')異常

七、咱們也可使用全局鉤子對好幾個字段進行校驗,好比password與re_password,使用validate(self, attrs),成功返回attrs,失敗則拋出異常exceptions.ValidationError('異常信息')

from rest_framework import serializers
from . import models
from rest_framework import exceptions

​
# 制定簡易基礎校驗規則查看有哪些規則
# serializers.DecimalField.max_value
# serializers.CharField.max_length
class UserModelSerializer(serializers.ModelSerializer):
    # 自定義字段,覆蓋model中的字段,model中沒有則必須寫write_only=True
    pwd = serializers.CharField(max_length=8, min_length=4, write_only=True)
    re_pwd = serializers.CharField(max_length=8, min_length=4, write_only=True)
​
    class Meta:
        model = models.User
        # 將全部的字段都寫在fields中
        fields = ['name', 'pwd', 'age', 'height', 'gender', 'img', 're_pwd']
        # 自定義基礎的校驗規則
        extra_kwargs = {
            'name': {
                # 有默認值或者能夠爲空,咱們也能夠限制必須提供
                'required': True,
                'max_length': 8,
                'error_messages': {  # 能夠被國際化配置替代
                    'max_length': '太長'
                }
            }
        }
    # 局部與全局鉤子與Meta同級,屬性序列化類的
    # 自定義單個字段校驗在局部鉤子中校驗,用validate_字段名(self, value)
    def validate_height(self, value):
        print(value)
        if value < 170:
            raise exceptions.ValidationError('過矮了')
        else:
            return value
​
    # 多字段之間校驗用全局鉤子,validate(self, attrs)  attrs是字段值的字典
    def validate(self, attrs):
        pwd = attrs.get('pwd')  # 只拿出來校驗
        re_pwd = attrs.pop('re_pwd')  # 必須pop出來,不能存入數據庫中
        if pwd != re_pwd:
            raise exceptions.ValidationError({'re_pwd': '兩次密碼不一致!'})
        else:
            return attrs
相關文章
相關標籤/搜索