drf序列化器與反序列化


什么是序列化與反序列化

"""
序列化:對象轉換為字符串用於傳輸
反序列化:字符串轉換為對象用於使用
"""

drf序列化與反序列化

"""
序列化:Model類對象轉換為字符串用於傳輸
反序列化:字符串轉換為Model類對象用於使用
"""

Model類

創建數據庫:終端
>: mysql -uroot -p密碼
>: create database 數據庫名 charset=utf8
配置數據庫:settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '數據庫名',
        'USER': 'root',
        'PASSWORD': '密碼'
    }
}
修改操作數據庫的模塊:項目init文件
import pymysql
pymysql.install_as_MySQLdb()
創建model類:models.py
from django.db import models
class User(models.Model):
    CHOICE_SEX = (
        (0, '男'),
        (1, '女')
    )
    name = models.CharField(max_length=32, verbose_name='姓名')
    password = models.CharField(max_length=64, verbose_name='密碼')
    sex = models.SmallIntegerField(choices=CHOICE_SEX, default=0)
    create_time = models.DateTimeField(auto_now_add=True, blank=True)

    class Meta:
        # 自定義創建的表名
        db_table = 'o_user'
        # admin界面中顯示的表面與表名復數形式
        verbose_name = '用戶'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name
注冊model類:admin.py
from django.contrib import admin
from api.models import User
admin.site.register(User)
數據庫遷移:在項目目錄下的終端
>: python3 manage.py makemigrations
>: python3 manage.py migrate
注冊超級用戶:在項目目錄下的終端
>: python3 manage.py createsuperuser
登陸admin頁面添加數據:瀏覽器
http://localhost:8000/admin/

路由分發

項目urls.py
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include('api.urls'))
]
api應用urls.py
from django.conf.urls import url
urlpatterns = [

]

獲取多資源 接口

序列化類:serializers.py
from rest_framework import serializers

# 為每一個Model類至少配一個Serializer類
class UserSerializer(serializers.Serializer):
    # 序列化一個Model類對象,其實就是序列化該類的每一個屬性
    name = serializers.CharField()
    password = serializers.CharField()
    sex = serializers.IntegerField()
    create_time = serializers.DateTimeField()
視圖類:views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import User
from .serializers import UserSerializer

# 對應路由:/users/
# 功能:get獲取所有 | post新增一個 | put修改一個 | delete刪除一個
class UsersAPIView(APIView):
    def get(self, request, *args, **kwargs):
        user_list = User.objects.all()
		
        # instance存放的是queryset對象,many需要設置為True
        user_data = UserSerializer(instance=user_list, many=True).data
        return Response(
            {
                'status': 0,
                'msg': 'ok',
                'results': user_data
            }
        )

序列化字段操作(自定義字段)

序列化類修訂:serializers.py
from rest_framework import serializers

# 為每一個Model類至少配一個Serializer類
class UserSerializer(serializers.Serializer):
    # 序列化一個Model類對象,其實就是序列化該類的每一個屬性
    # 注意1:Model類與Serializer類是通過屬性名建立關聯的 - 屬性名必須依照
    name = serializers.CharField()
    password = serializers.CharField()
    # sex = serializers.IntegerField()
    # 注意2:不需要通過給前台的數據,不需要提供該屬性的序列化
    # create_time = serializers.DateTimeField()

    # 注意3:serializers.SerializerMethodField()可以產生自定義序列化屬性(不需要和Model類屬性同步),
    #       但要為其綁定一個提供值的函數,函數名為 get_屬性(self, obj) (obj為參與序列化的Model類對象)
    gender = serializers.SerializerMethodField()
    def get_gender(self, obj):
        # 該函數的返回值就作為對應自定義數據序列化后的值
        return obj.get_sex_display()

新增單資源 接口

序列化類(反序列化類):serializers.py
from rest_framework import serializers
from .models import User


class UserDeserializer(serializers.Serializer):
    name = serializers.CharField(label='姓名', max_length=32, min_length=3, error_messages={
        'max_length': '姓名太長',
        'min_length': '姓名太短'
    })
    password = serializers.CharField(label='密碼', max_length=64, min_length=3, error_messages={
        'max_length': '密碼太長',
        'min_length': '密碼太短'
    })
    sex = serializers.IntegerField()
    # required=False該字段前台可以不用傳(不參與校驗)
    create_time = serializers.DateTimeField(required=False)

    # 完成ORM的操作
    # def save(self):  # 不能直接重寫save,因為系統的save可以完成新增或修改
    #     # print(self.validated_data)
    #     User.objects.create(**self.validated_data)

    # 為post接口提供新增Model類對象的功能
    def create(self, validated_data):
        # 返回值:Model類要新增的對象
        return User.objects.create(**validated_data)
視圖類:views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import User
from .serializers import UserSerializer

# 對應路由:/users/
# 功能:get獲取所有 | post新增一個 | put修改一個 | delete刪除一個
class UsersAPIView(APIView):
    # 新增一個資源
    def post(self, request, *args, **kwargs):
        user_deser = UserDeserializer(data=request.data)
        # raise_exception值為True,當校驗失敗,直接返回校驗失敗的錯誤信息
        # result = user_deser.is_valid(raise_exception=True)
        result = user_deser.is_valid()
        if result:
            new_user_obj = user_deser.save()
            return Response({
                'status': 0,
                'msg': 'success',
                'result': UserSerializer(new_user_obj).data
            })
        else:
            return Response({
                'status': 1,
                'msg': 'failed',
                'results': user_deser.errors
            })


更新單資源 接口

序列化類(反序列化類):serializers.py
from rest_framework import serializers
from .models import User


class UserDeserializer(serializers.Serializer):
    name = serializers.CharField(label='姓名', max_length=32, min_length=3, error_messages={
        'max_length': '姓名太長',
        'min_length': '姓名太短'
    })
    password = serializers.CharField(label='密碼', max_length=64, min_length=3, error_messages={
        'max_length': '密碼太長',
        'min_length': '密碼太短'
    })
    sex = serializers.IntegerField()
    # required=False該字段前台可以不用傳(不參與校驗)
    create_time = serializers.DateTimeField(required=False)

    # 完成ORM的操作
    # def save(self):  # 不能直接重寫save,因為系統的save可以完成新增或修改
    #     # print(self.validated_data)
    #     User.objects.create(**self.validated_data)

    # 為post接口提供新增Model類對象的功能
    def create(self, validated_data):
        # 返回值:Model類要新增的對象
        return User.objects.create(**validated_data)
    
    # 為put接口提供更新Model類對象的功能
    def update(self, instance, validated_data):
        # 操作model對象
        # instance.name = validated_data.get('name')
        # instance.password = validated_data.get('password')
        # instance.sex = validated_data.get('sex')
        # instance.save()
        # 操作queryset對象
        instance.update(**validated_data)
        return instance
視圖類:views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import User
from .serializers import UserSerializer

# 對應路由:/users/
# 功能:get獲取所有 | post新增一個 | put修改一個 | delete刪除一個
class UsersAPIView(APIView):
	# 更新一個資源
    def put(self, request, *args, **kwargs):
        # 要更新的資源的主鍵
        pk = kwargs.get('pk')
		
        # 操作更新時可以選擇操作 queryset對象 或 model對象
		# 操作model對象
        # old_user_obj = User.objects.get(pk=pk)
        # user_deser = UserDeserializer(instance=old_user_obj, data=request.data)

        # 操作queryset對象
        old_user_query = User.objects.filter(pk=pk)
        user_deser = UserDeserializer(instance=old_user_query, data=request.data)

        # raise_exception值為True,當校驗失敗,直接返回校驗失敗的錯誤信息
        # result = user_deser.is_valid(raise_exception=True)
        result = user_deser.is_valid()
        if result:
            # new_user_obj = user_deser.save()  # 操作model對象
            new_user_query = user_deser.save()  # 操作queryset對象
            new_user_obj = new_user_query.first()
            return Response({
                'status': 0,
                'msg': 'success',
                'result': UserSerializer(new_user_obj).data
            })
        else:
            return Response({
                'status': 1,
                'msg': 'failed',
                'results': user_deser.errors
            })

刪除單資源 接口

重構Model新增字段:models.py
class User(models.Model):
    CHOICE_SEX = (
        (0, '男'),
        (1, '女')
    )
    name = models.CharField(max_length=32, verbose_name='姓名')
    password = models.CharField(max_length=64, verbose_name='密碼')
    sex = models.SmallIntegerField(choices=CHOICE_SEX, default=0)
    create_time = models.DateTimeField(auto_now_add=True, blank=True)
    # 新增:數據刪除不是從數據庫刪除記錄,而是修改記錄狀態,標示為已刪除即可
    is_delete = models.BooleanField(default=False)

    class Meta:
        # 自定義創建的表名
        db_table = 'o_user'
        # admin界面中顯示的表面與表名復數形式
        verbose_name = '用戶'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name
數據庫遷移:在項目目錄下的終端
>: python3 manage.py makemigrations
>: python3 manage.py migrate
視圖類接口:views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import User
from .serializers import UserSerializer

# 對應路由:/users/
# 功能:get獲取所有 | post新增一個 | put修改一個 | delete刪除一個
class UsersAPIView(APIView):
	# 刪除一個資源
    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        try:
            delete_user_obj = User.objects.get(pk=pk, is_delete=False)
            # 完成刪除信息的更新
            delete_user_obj.is_delete = True
            delete_user_obj.save()
            return Response()
        except:
            return Response({
                'status': 1,
                'msg': '數據刪除失敗'
            })

獲取單資源 接口

序列化類:serializers.py
from rest_framework import serializers

# 為每一個Model類至少配一個Serializer類
class UserSerializer(serializers.Serializer):
    # 序列化一個Model類對象,其實就是序列化該類的每一個屬性
    name = serializers.CharField()
    password = serializers.CharField()
    sex = serializers.IntegerField()
    create_time = serializers.DateTimeField()
視圖類:views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import User
from .serializers import UserSerializer

# 對應路由:/users/
# 功能:get獲取所有 | post新增一個 | put修改一個 | delete刪除一個
class UsersAPIView(APIView):
    def get(self, request, *args, **kwargs):
         pk = kwargs.get('pk', None)

        if not pk:
            user_query = User.objects.filter(is_delete=False).all()
        else:
            user_query = User.objects.filter(is_delete=False, pk=pk)
            # 如果只操作一個對象,many參數需要為False(默認值)
            # user_obj = User.objects.filter(is_delete=False, pk=pk).first()
            # user_data = UserSerializer(instance=user_obj, many=False).data

        user_data = UserSerializer(instance=user_query, many=True).data
        return Response(
            {
                'status': 0,
                'msg': 'ok',
                'results': user_data
            }
        )

序列化基礎:重點內容

模型類:models.py
from django.db import models

# Create your models here.

class User(models.Model):
    CHOICE_SEX = (
        (0, '男'),
        (1, '女')
    )
    name = models.CharField(max_length=32, verbose_name='姓名')
    password = models.CharField(max_length=64, verbose_name='密碼')
    sex = models.SmallIntegerField(choices=CHOICE_SEX, default=0)
    create_time = models.DateTimeField(auto_now_add=True, blank=True)
    # 數據刪除不是從數據庫刪除記錄,而是修改記錄狀態,標示為已刪除即可
    is_delete = models.BooleanField(default=False)

    class Meta:
        # 自定義創建的表名
        db_table = 'o_user'
        # admin界面中顯示的表面與表名復數形式
        verbose_name = '用戶'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name
序列化類:
from rest_framework import serializers
from .models import User

class UserSerializer(serializers.Serializer):
    # 序列化和反序列化都可以使用
    name = serializers.CharField(label='姓名', max_length=32, min_length=3, error_messages={
        'max_length': '姓名太長',
        'min_length': '姓名太短'
    })
    password = serializers.CharField(label='密碼', max_length=64, min_length=3, error_messages={
        'max_length': '密碼太長',
        'min_length': '密碼太短'
    })
    # 只有反序列化使用 - 用 write_only=True 標示只參與反序列化
    sex = serializers.IntegerField(write_only=True)
    # 只有序列化使用 - 自定義字段 - 用 read_only=True 標示只參與序列化
    gender = serializers.SerializerMethodField(read_only=True)
    def get_gender(self, obj):
        return obj.get_sex_display()
    # 序列化與反序列化都不使用 - 1)注釋 | 2)required=False, write_only=True
    create_time = serializers.DateTimeField(required=False, write_only=True)

    # 為全局校驗鈎子新增校驗字段
    re_password = serializers.CharField(label='確認密碼', max_length=64, min_length=3, write_only=True, error_messages={
        'max_length': '確認密碼太長',
        'min_length': '確認密碼太短'
    })


    # 反序列化兩大方法重寫 - 新增create | 更新update
    # 為post接口提供新增Model類對象的功能
    def create(self, validated_data):
        # 返回值:Model類要新增的對象
        return User.objects.create(**validated_data)

    # 為put接口提供更新Model類對象的功能
    def update(self, instance, validated_data):
        instance.update(**validated_data)
        # 返回更新后的instance
        return instance


    # 局部鈎子
    def validate_sex(self, value):
        if value not in (0, 1):
            raise serializers.ValidationError('未知性別')
        return value

    # 全局鈎子
    def validate(self, attrs):
        re_password = attrs.pop('re_password')
        password = attrs.get('password')
        if re_password != password:
            raise serializers.ValidationError('二次密碼不一致')
        return attrs
視圖類:
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import User
from .serializers import UserSerializer

# 對應路由:/users/ | /users/pk/
# 功能:get獲取所有 | post新增一個 | put修改一個 | delete刪除一個 | get獲取一個
class UsersAPIView(APIView):
    # 獲取所有資源 | 單個資源
    def get(self, request, *args, **kwargs):
        # 單個資源的主鍵
        pk = kwargs.get('pk', None)
        if not pk:
            user_query = User.objects.filter(is_delete=False).all()
        else:
            user_query = User.objects.filter(is_delete=False, pk=pk)

        user_data = UserSerializer(instance=user_query, many=True).data
        return Response(
            {
                'status': 0,
                'msg': 'ok',
                'results': user_data
            }
        )

    # 新增一個資源
    def post(self, request, *args, **kwargs):
        user_deser = UserSerializer(data=request.data)

        # raise_exception值為True,當校驗失敗,直接返回校驗失敗的錯誤信息
        # result = user_deser.is_valid(raise_exception=True)
        result = user_deser.is_valid()
        if result:
            new_user_obj = user_deser.save()
            return Response({
                'status': 0,
                'msg': 'success',
                'result': UserSerializer(new_user_obj).data
            })
        else:
            return Response({
                'status': 1,
                'msg': 'failed',
                'results': user_deser.errors
            })

    # 更新一個資源
    def put(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        old_user_query = User.objects.filter(pk=pk, is_delete=False)
        # 沒有數據
        if not old_user_query:
            return Response({
                'status': 1,
                'msg': 'update failed',
            })

        user_deser = UserSerializer(instance=old_user_query, data=request.data)
        result = user_deser.is_valid()
        if result:
            new_user_query = user_deser.save()
            new_user_obj = new_user_query.first()
            return Response({
                'status': 0,
                'msg': 'success',
                'result': UserSerializer(new_user_obj).data
            })
        else:
            return Response({
                'status': 1,
                'msg': 'failed',
                'results': user_deser.errors
            })

    # 刪除一個資源
    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        try:
            delete_user_obj = User.objects.get(pk=pk, is_delete=False)
            # 完成刪除信息的更新
            delete_user_obj.is_delete = True
            delete_user_obj.save()
            return Response()
        except:
            return Response({
                'status': 1,
                'msg': '數據刪除失敗'
            })


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM