drf中的序列化家族

序列化家族:Serializer類;modelSerializer類和ListSerializer類

"""一、Serializer類:底層序列化-瞭解的類
重點:單表序列化

二、modelSerializer類:模型序列化類-核心類
重點:多表序列化

三、ListSerializer類:羣操做序列化類-輔助類
    重點:輔助完成單表多表羣增羣改操做"""

import sys

# 標準輸出流
sys.stdout.write('123\n')
sys.stdout.write('456\n')

# 標準輸入流
res=sys.stdin.readline()
print(res)

# 標準錯誤流
sys.stderr.write('jdjf\n')
sys.stderr.write('hsh\n')

內部類:
def fn():
    def func():
        pass


class A:
    class B:  # B類的名稱能夠經過A類來訪問
        x = 10
        y = 20


print(A.B.x)  # 10

 

Serializer序列化(瞭解)

視圖類

序列化類

一、設置序列化字段,字段名與字段類型要處理的model類對應(只參與序列化的類型不須要設置條件)
二、model類中有的字段,可是序列化中沒前端

有對應字段,該字段不參加序列化
三、自定義序列化字段(方法一),字段類型爲SerializerMethodField(),值有get_自定義字段名(self, obj)方法提供,通常值都與參與序列化的model對象(model_obj)有關數據庫

from rest_framework import serializers
from django.conf import settings
from . import models


class UserSerializer(serializers.Serializer):
    # 1)字段名與字段類型要處理的model類對應
    # 2)不提供的字段,就不參與序列化給前臺
    # 3)能夠自定義序列化字段,採用方法序列化,方法固定兩個參數,第二個參數就是參與序列化的model對象
    #   (嚴重不建議自定義字段與數據庫字段重名,由get_自定義字段名方法的返回值提供字段值)
    usernamae = serializers.CharField()
    # sex=serializers.SerializerMethodField()不建議這樣命名
    gender = serializers.SerializerMethodField()

    def get_gender(self, obj):
        return obj.get_sex_display()  # 返回的值給gender

    # 注:在高級序列化與高級視圖類中,drf默認幫咱們處理圖片等子資源
    icon = serializers.SerializerMethodField()

    def get_icon(self, obj):
        return '%s%s%s' % (settings.BASE_URL, settings.MEDIA_URL, obj.img)

 

Serializer反序列化(瞭解)

# 單查羣查
    #視圖類序列化過程
    #1)ORM操做獲得數據
    #2)將數據序列化成能夠返回給前臺的數據
    #3)返回數據給前臺

    def get(self,request,*args,**kwargs):
        pk=kwargs.get('pk')
        if pk:
            user_obj=models.User.objects.filter(is_delete=False,pk=pk).first()
            if not user_obj:
                return Response({
                    'status':1,
                    'msg':'pk error',
                },status=400)

            user_ser=serializers.UserSerializer(user_obj,many=False)#將從數據庫查到的數據對象傳進去,many默認爲False,單查,返回的也是一個類實例化的對象
            user_obj_data=user_ser.data
            return Response({
                'status':0,
                'msg':'ok',
                'results':user_obj_data
            })
        else:
            #將對象對外提供的字段,已經整個序列化過程封裝,造成序列化類
            user_query=models.User.objects.filter(is_delete=False).all()
            user_ser=serializers.UserSerializer(user_query,many=True)#將從數據庫查到的query對象傳進去,many爲True,羣查,返回的也是一個類實例化的對象
            user_list_data=user_ser.data
            return Response({
                'status': 0,
                'msg': 'ok',
                'results': user_list_data
            })

 

視圖類:

 #單增
    #視圖類反序列化過程
    #1)從請求對象中獲取前臺提交的數據
    #2)交給序列化類完成反序列化(數據的校驗)
    #3)藉助序列化類完成數據入庫
    #4)反饋給前臺處理結果

    def post(self,request,*args,**kwargs):
        request_data=request.data#取出前端傳來的數據
        user_ser=serializers.UserDeSerializer(data=request_data)
        if user_ser.is_valid():
            #入庫
            user_obj=user_ser.save()
            return Response({
                'status':0,
                'msg':'ok',
                'results':serializers.UserSerializer(user_obj).data#將入庫獲得的user對象從新序列化的數據返回給前臺
            })
        else:
            return Response({
                'status': 1,
                'msg': user_ser.errors,
            })

 

序列化類

一、系統校驗字段與自定義校驗字段定義沒有區別:字段 = serializers.字段類型(條件)
二、自定義校驗字段是不能直接入庫的,須要設置入庫規則,或將其移除不入庫(這類字段就是參與全局校驗用的)
三、全部字段均可以設置對應局部鉤子進行校驗,鉤子方法 validate_字段名(self, 字段值value)
規則:成功直接返回value,失敗拋出校驗失敗信息ValidationError('錯誤信息')
四、一個序列化類存在一個全局鉤子能夠對全部字段進行全局校驗,鉤子方法 validate(self, 全部字段值字典attrs)
規則:成功直接返回attrs,失敗拋出校驗失敗信息ValidationError({'異常字段', '錯誤信息'})
五、重寫create方法實現增入庫,返回入庫成功的對象
六、重寫update方法實現改入庫,返回入庫成功的對象django

class UserDeSerializer(serializers.Serializer):
    # 系統校驗字段
    usernamae = serializers.CharField(min_length=3, max_length=16, error_messages={
        'min_length': '過短',
        'max_length': '太長'
    })
    password = serializers.CharField(min_length=3, max_length=16)
    # 不寫,不參加反序列化,寫了就必須參加反序列化(但能夠設置required=False取消必須)
    # required=False的字段,前臺不提供,走默認值,提供就必定進行校驗,不寫前臺不提供都採用默認值
    sex = serializers.BooleanField(required=False)

    # 自定義校驗字段:其設置語法與系統字段沒有區別,可是這些字段不能參與入庫操做,須要在全局鉤子中,將其取出
    re_password = serializers.CharField(min_length=3, max_length=16)

    # 局部鉤子
    # 方法就是validate_校驗的字段名(self,校驗的字段數據)
    # 校驗規則:成功直接返回value,失敗跑出校驗失敗信息
    def validate_usernamae(self, value):
        if 'g' in value.lower():
            raise serializers.ValidationError('名字中不能有g')
        return value

    # 全局鉤子
    # 方法就是validate(self,全部的校驗數據)
    # 校驗規則:成功直接返回attrs,失敗跑出校驗失敗信息
    def validate(self, attrs):
        password = attrs.get('password')
        re_password = attrs.pop('re_password')
        if password != re_password:
            raise serializers.ValidationError({'re_password':'兩次密碼不一致'})
        return attrs

    # 在視圖類中調用序列化類的save方法完成入庫,Serializer類能作的增入庫走create方法,改入庫走update方法
    # 但Serializer沒有提供兩個方法的實現體 本身寫

    def create(self, validated_data):
        return models.User.objects.create(**validated_data)

    #instance要被修改的對象,validated_data表明校驗後用來蓋instance的數據
    def update(self, instance, validated_data):
        #用戶名不能被修改
        validated_data.pop('usernamae')
        models.User.objects.filter(pk=instance.id).update(**validated_data)
        return instance

ModelSerializer序列化與反序列化(重點)

視圖類

class UserV3APIView(APIView):
    # 單查羣查
    def get(self,request,*args,**kwargs):
        pk=kwargs.get('pk')
        if pk:
            user_obj=models.User.objects.filter(is_delete=False,pk=pk).first()
            if not user_obj:
                return Response({
                    'status':1,
                    'msg':'pk error',
                },status=400)

            user_ser=serializers.UserModelSerializer(user_obj,many=False)#將從數據庫查到的數據對象傳進去,many默認爲False,單查,返回的也是一個類實例化的對象

            return Response({
                'status':0,
                'msg':'ok',
                'results':user_ser.data
            })
        else:
            #將對象對外提供的字段,已經整個序列化過程封裝,造成序列化類
            user_query=models.User.objects.filter(is_delete=False).all()
            user_ser=serializers.UserModelSerializer(user_query,many=True)#將從數據庫查到的query對象傳進去,many爲True,羣查,返回的也是一個類實例化的對象
            return Response({
                'status': 0,
                'msg': 'ok',
                'results': user_ser.data
            })
 # 單增
    def post(self,request,*args,**kwargs):
        user_ser=serializers.UserModelSerializer(data=request.data)
        if user_ser.is_valid():
            #入庫
            user_obj=user_ser.save()
            return Response({
                'status':0,
                'msg':'ok',
                'results':serializers.UserModelSerializer(user_obj).data#將入庫獲得的user對象從新序列化的數據返回給前臺
            })
        else:
            return Response({
                'status': 1,
                'msg': user_ser.errors,
            })

 

序列化

ModelSerializer類序列化與反序列化總結
一、序列化類繼承ModelSerializer,因此須要在配置類Meta中進行配置
二、model配置:綁定序列化相關的Model表
三、fields配置:採用 插拔式 設置全部參與序列化與反序列化字段
四、extra_kwargs配置:
劃分系統字段爲三種:只讀(read_only)、只寫(write_only)、可讀可寫(不設置)
字段是否必須:required
選填字段:在extra_kwargs進行配置,但不設置required,且有默認值
五、自定義序列化字段:
第一種(不提倡):在序列化類中用SerializerMethodField()來實現
第二種(提倡):在模型類中用@property來實現,可插拔
六、自定義反序列化字段:
同Serializer類,且規則只能在此聲明中設置,或是在鉤子中設置,在extra_kwargs中對其設置的無效
自定義反序列化字段與系統字段,設置規則同樣,因此必須設置 write_only
七、局部鉤子,全局鉤子同Serializer類
八、不須要重寫create和update方法post

class UserModelSerializer(serializers.ModelSerializer):
    #第一種自定義序列化字段,該字段必須在fileds中設置
    #第二種:在models.py中定義
    # gender=serializers.SerializerMethodField()
    # def get_gender(self,obj):
    #     return obj.get_sex_display()

    #自定義反序列化字段同Serializers類,且規則只能在此聲明中設置,或是在鉤子中設置
    #在extra_kwargs中對其設置的無效
    #注:自定義反序列化字段與系統字段,設置規則同樣,全部必須設置write_only
    re_password=serializers.CharField(min_length=3,max_length=16,write_only=True)

    class Meta:
        model=models.User
        #fileds採用插拔式  設置全部參與序列化字段
        fields=('usernamae','gender','icon','password','sex','re_password')
        extra_kwargs={
            'usernamae':{#系統字段不設置read_only和write_only,默認都參加
                'min_length':3,
                'max_length':10,
                'error_messages':{
                    'min_length': '過短',
                    'max_length': '太長'
                }
            },
            'gender':{
                'read_only':True,#自定義的序列化字段默認就是read_only,且不能修改,能夠忽略
            },
            'password':{
                'write_only':True,
            },
            'sex':{ #像sex有默認值的字段,爲選填字段(‘required’:True能夠將其變爲必填字段
                'write_only':True
                # 'required':True
            }
        }

    # 局部全局鉤子同Serializer類,是與 Meta 同縮進的
    def validate_username(self, value):
        if 'g' in value.lower():
            raise serializers.ValidationError('名字中不能有g')
        return value

    def validate(self, attrs):
        password = attrs.get('password')
        re_password = attrs.pop('re_password')
        if password != re_password:
            raise serializers.ValidationError({'re_password': '兩次密碼不一致'})
        return attrs
# create和update方法不須要再重寫,ModelSerializer類已提供,且支持全部關係下的連表操做

 

模型類

from django.db import models

# Create your models here.
class User(models.Model):
    SEX_CHOICES=(
        (0,''),
        (1,'')
    )
    usernamae=models.CharField(max_length=64,verbose_name='用戶名',blank=True,unique=True)
    password=models.CharField(max_length=64,verbose_name='密碼')
    sex=models.IntegerField(choices=SEX_CHOICES,default=0,verbose_name='性別')
    img=models.ImageField(upload_to='img',default='img/default.png',verbose_name='頭像')
    #開發中,數據不會直接刪除,用過字段控制
    is_delete=models.BooleanField(default=False,verbose_name='是否註銷')
    #數據庫數據入庫,通常都會記錄該數據第一次入庫時間,有時候還會記錄最後一次更新時間
    create_time=models.DateTimeField(auto_now_add=True,verbose_name='建立時間')

    #第二種自定義序列化字段(插拔式,提倡使用)
    @property
    def gender(self):
        return self.get_sex_display()

    @property
    def icon(self):
        from django.conf import settings
        return '%s%s%s' % (settings.BASE_URL, settings.MEDIA_URL, self.img)

    class Meta:#配置類,給你所屬類提供配置信息
        db_table='old_boy_user'
        verbose_name_plural='用戶表'

    def __str__(self):#不要在這裏進行連表操做,admin頁面可能會崩潰
        return self.usernamae

 

"""
相關文章
相關標籤/搜索