1. 程式人生 > 其它 >drf : 序列化器Serializer

drf : 序列化器Serializer

序列化器Serializer

作用:

  1. 序列化,序列化器會把模型物件轉換成字典,經過request以後變成json字串
  2. 反序列化,把客戶端傳送過來的資料,經過request以後變成字典(request.data),序列化器(類)可以把字典轉成模型
  3. 反序列化,完成資料校驗功能

本質就是寫一個類,繼承基類。

可以完成序列化,反序列化和資料校驗。

讀取資料為序列化,新增為反序列化。

通過serizlizer實現五個介面,此為第一步。

查詢所有介面,新增資料介面

serizlizer.py

"""
與表沒有關係,需要自己建關係
from rest_framework.serializers import Serializer
"""
from rest_framework import serializers

# 需要序列化和反序列化Book表,可稱呼為序列化類
class BoookSerializers(serializers.Serializer):
    # 寫欄位(需要序列化,反序列化的欄位)
    name = serializers.CharField()
    price = serializers.IntegerField()
    publish = serializers.CharField()
    
    # 新增需要重寫create
    def create(self, validated_data):
        # {'name': '新增2', 'price': 10, 'publish': '測試出版社'}
        # print(validated_data)
        book = Books.objects.create(**validated_data)
        # Books object (7)
        # print(book)
        return book

views.py,發序列化新增,序列化讀取。

"""
drf使用方式:CBV,繼承的類,是drf提供的類,APIView
使用drf 多了一個Response類
"""
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
from .serizlizer import BoookSerializers
from .models import Books


class BookAPIView(APIView):
    # 查詢所有的介面
    def get(self, request, *args, **kwargs):
        # 從資料庫中把所有的資料取出,取出Books所有的queryset物件
        book_list = Books.objects.all()
        # <QuerySet [<Books: Books object (1)>, <Books: Books object (3)>]>
        print(book_list)
        """
        類例項化得到物件(ser),並轉為字典,此處為序列化過程,把queryset轉成字典
        BookSerializers(
                        需要序列化的queryset物件,
                        data=None可以不傳,
                        如果序列化多條資料需要加many=True)
        """
        ser = BoookSerializers(instance=book_list, many=True)
        """
        字典
        [
        OrderedDict([('name', '葫蘆娃'), ('price', 10), ('publish', '測試出版社')]), 
        OrderedDict([('name', '互擼娃'), ('price', 10000), ('publish', '娃哈哈出版社')])
        ]
        """
        print(ser.data)
        # <class 'rest_framework.utils.serializer_helpers.ReturnList'>
        print(type(ser.data))
        # ser.data 序列化轉成字典
        return Response(ser.data)
      
    # 新增
    def post(self,request,*args, **kwargs):
        # <rest_framework.request.Request: POST '/books/'>
        print(request)
        # {'name': '新增8', 'price': 10, 'publish': '測試出版社'}
        print(request.data)
        ser = BookSerializers(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response(ser.data)

url.py

from django.contrib import admin
from django.urls import path
from app01 import views
# from rest_framework.routers import SimpleRouter


urlpatterns = [
    path('admin/', admin.site.urls),

    # drf 繼承APIView 的路由,向books地址傳送請求,將所有圖書返回
    path('books/', views.BookAPIView.as_view())

]

查詢單個介面,刪除單個介面,修改

Serializers.py

from rest_framework import serializers


# 需要序列化和反序列化Book表
class BookSerializers(serializers.Serializer):
    # 寫欄位(需要序列化,反序列化的欄位)
    name = serializers.CharField()
    price = serializers.IntegerField()
    publish = serializers.CharField()

    # 如果要更新,一定要重寫updata方法
    def update(self, instance, validated_data):
        # Books object (1)
        print(instance)
        instance.name = validated_data.get('name')
        # jajajaj 修改的資料
        print(instance.name)
        instance.price = validated_data.get('price')
        instance.publish = validated_data.get('publish')
        # 儲存
        instance.save()
        # 返回
        return instance

url.py

from django.contrib import admin
from django.urls import path
from app01 import views
# from rest_framework.routers import SimpleRouter


urlpatterns = [
    path('admin/', admin.site.urls),

    # drf 繼承APIView 的路由,向books地址傳送請求,將所有圖書返回
    path('books/', views.BookAPIView.as_view()),
    # <int:pk> 轉換器,int為定義型別,資料型別可自定義。
    path('books/<int:pk>', views.BookDetilAPIView.as_view()),
]

views.py

class BookDetilAPIView(APIView):
    # 查詢單個介面
    def get(self,request,pk):
        book = Books.objects.filter(pk=pk).first()
        # Books object (1)
        # print(book)
        # <class 'app01.models.Books'>
        # print(type(book))
        """
        此處為序列化過程,把queryset轉成字典
        many=True 需要改為False,此時為查詢單條資料,不寫,many預設為False,
        """
        ser = BookSerializers(instance=book)
        return Response(ser.data)

    # 刪除單個介面
    def delete(self,request,pk):
        Books.objects.filter(pk=pk).delete()
        return Response()

    # 修改單條資料
    def put(self,request,pk):
        # <rest_framework.request.Request: PUT '/books/1'>
        # print(request)
        book = Books.objects.filter(pk=pk).first()
        # {'name': '哈哈哈', 'price': 10, 'publish': '測試出版社'},內部自動返序列化
        # print(request.data)
        ser = BookSerializers(instance=book,data=request.data)
        # 校驗資料
        if ser.is_valid():
            ser.save()
            return Response(ser.data)