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

序列化器-Serializer

目錄

序列化器-Serializer

作用:

  1. 序列化,序列化器會把模型物件轉換成字典,經過response以後變成json字串
  2. 反序列化,把客戶端傳送過來的資料,經過request以後變成字典,序列化器可以把字典轉成模型
  3. 反序列化,完成資料校驗功能
#先在models.py中寫建立表
from django.db import models

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=3)
    author = models.CharField(max_length=32)
    publish = models.CharField(max_length=32)

1、序列化器使用

寫一個序列化類,繼承Serializer
在類中寫要序列化的欄位,想要序列化哪個欄位,就在類中寫哪個欄位
在檢視類中使用,匯入自己寫的序列化類(ser.py)---》例項化得到序列化類的物件,把要序列化的物件傳入
序列化類的物件.data  是一個字典
把字典返回,如果不使用rest_framework提供的Resposne,就得使用JsonResponse
# 自己建立的ser.py檔案中寫序列化類

from rest_framework import serializers

# 需要繼承Serializer
class BookSeralizer(serializers.Serializer):
    #想要序列化哪個欄位,就在類中寫哪個欄位
    id = serializers.CharField()
    name = serializers.CharField()
    price = serializers.CharField()
    author = serializers.CharField()
    publish = serializers.CharField()
#urls.py

re_path('books/(?P<pk>\d+)', views.BookView.as_view())
#views.py
from rest_framework.views import APIView
from App.models import Book
from App.ser import BookSeralizer
from rest_framework.response import Response  # drf提供的響應物件

class BookView(APIView):
    def get(self, request, pk):
        book_obj = Book.objects.filter(pk=pk).first()
        # 序列化誰,就把誰傳過來
        book_ser = BookSeralizer(book_obj)  # 呼叫類的__init__方法
        # 序列化物件.data就是序列化後的字典
        return Response(book_ser.data)

如果使用JsonResponse返回資料,效果如下:

如果使用JsonResponse返回資料,就不需要在settings.py中註冊rest_framework

注意

如果碰到下面的報錯,需要把rest_framework在settings.py中的app中註冊

2、序列化類的欄位型別

有很多,
只需記住 CharField IntegerField,DateField......

欄位型別:

選項引數:

通用引數:

3、序列化元件修改儲存資料

1.寫一個序列化類,繼承Serializer
2.在類中寫要反序列化的欄位,想要反序列化哪個欄位,就在類中寫哪個欄位,欄位的屬性(max_length.....)
3.在檢視類中使用,匯入---》例項化得到序列化類的物件,把要修改的資料傳入         
		book_ser = BookSeralizer(book_obj, request.data)
    	book_ser = BookSeralizer(instance=book_obj, data=request.data)
#自己建立的ser.py檔案

from rest_framework import serializers
from rest_framework.exceptions import ValidationError


# 需要繼承Serializer
class BookSeralizer(serializers.Serializer):
    name = serializers.CharField(max_length=16, min_length=4)
    price = serializers.CharField()
    author = serializers.CharField()
    publish = serializers.CharField()

    def update(self, instance, validated_data):
        # instance是Book這個物件
        # validated_data是校驗後的資料
        instance.name = validated_data.get('name')
        instance.price = validated_data.get('price')
        instance.author = validated_data.get("author")
        instance.publish = validated_data.get('publish')
        instance.save()  # book.save() 是django 的orm提供的
        return instance
#urls.py
re_path('books/(?P<pk>\d+)', views.BookView.as_view())


#views.py
from rest_framework.views import APIView
from App.models import Book
from App.ser import BookSeralizer
from rest_framework.response import Response  # drf提供的響應物件

class BookView(APIView):
    def put(self, request, pk):
        response_msg = {'code': 100, 'msg': ''}
        # 找到要改的物件
        book_obj = Book.objects.filter(pk=pk).first()
        # 得到序列化類的物件
        # book_ser = BookSeralizer(book_obj, request.data)
        book_ser = BookSeralizer(instance=book_obj, data=request.data)
        # 要驗證(和forms元件校驗一樣)
        if book_ser.is_valid():  # 表示驗證通過
            book_ser.save()
            response_msg['msg'] = '資料校驗成功'
            response_msg['data'] = book_ser.data

        else:
            response_msg['code'] = 101
            response_msg['msg'] = '資料校驗失敗'
            response_msg['data'] = book_ser.errors
        return Response(response_msg)

4、序列化元件校驗資料

1.寫一個序列化類,繼承Serializer
2.在類中寫要反序列化的欄位,想要反序列化哪個欄位,就在類中寫哪個欄位,欄位的屬性(max_length.....)
3.在檢視類中使用,匯入---》例項化得到序列化類的物件,把要修改的資料傳入         
		book_ser = BookSeralizer(book_obj, request.data)
    	book_ser = BookSeralizer(instance=book_obj, data=request.data)

4.資料校驗 if book_ser.is_valid()
5.如果校驗通過就儲存,檢視中呼叫 序列化物件 ook_ser.save() 序列化物件.save()
6.如果不通過,邏輯自己寫
7.如果欄位的校驗規則不夠,可以寫鉤子函式(區域性和全域性)
	# 區域性鉤子
	def validate_price(self, data):  # validate_欄位名,接受一個引數
        # print(type(data))
        # print(data)
        if float(data) < 10:
            # 校驗失敗,拋異常
            raise ValidationError('價格太低')
        return data
 
     # 全域性鉤子
    def validate(self, validated_data): 
        author = validated_data.get("author")
        publish = validated_data.get("publish")
        if author == publish:
            raise ValidationError("作者跟出版社一樣")
            return validated_data
8. 可以使用欄位的validators來校驗
		author = serializers.CharField(validators=[check_author]), 來校驗
        -寫一個函式
        def check_author(data):
            if data.startswith('sb'):
                raise ValidationError('作者名不能以sb開頭')
        -配置:author =validators=[check_author]

re_path('books/(?P<pk>\d+)', views.BookView.as_view())

區域性(全域性)鉤子校驗:

#自己建立的ser.py檔案

from rest_framework import serializers
from rest_framework.exceptions import ValidationError


# 需要繼承Serializer
class BookSeralizer(serializers.Serializer):
    name = serializers.CharField(max_length=16, min_length=4)
    price = serializers.CharField()
    author = serializers.CharField()
    publish = serializers.CharField()

    # 區域性鉤子
    def validate_price(self, data):  # validate_欄位名,接受一個引數
        # print(type(data))
        # print(data)
         # 如果價格小於10,校驗不通過
        if float(data) < 10:
            # 校驗失敗,拋異常
            raise ValidationError('價格太低')
        return data
    
	 # 全域性鉤子
    def validate(self, validated_data): 
        author = validated_data.get("author")
        publish = validated_data.get("publish")
        if author == publish:
            raise ValidationError("作者跟出版社一樣")
            return validated_data


    def update(self, instance, validated_data):
        # instance是Book這個物件
        # validated_data是校驗後的資料
        instance.name = validated_data.get('name')
        instance.price = validated_data.get('price')
        instance.author = validated_data.get("author")
        instance.publish = validated_data.get('publish')
        instance.save()  # book.save() 是django 的orm提供的
        return instance

自己邏輯上的校驗:

#views.py

from rest_framework.views import APIView
from App.models import Book
from App.ser import BookSeralizer
from rest_framework.response import Response  # drf提供的響應物件

class BookView(APIView):
    def put(self, request, pk):
        response_msg = {'code': 100, 'msg': ''}
        # 找到要改的物件
        book_obj = Book.objects.filter(pk=pk).first()
        # 得到序列化類的物件
        # book_ser = BookSeralizer(book_obj, request.data)
        book_ser = BookSeralizer(instance=book_obj, data=request.data)
        # 要驗證(和forms元件校驗一樣)
        if book_ser.is_valid():  # 表示驗證通過
            book_ser.save()
            response_msg['msg'] = '資料校驗成功'
            response_msg['data'] = book_ser.data

        else:
            response_msg['code'] = 101
            response_msg['msg'] = '資料校驗失敗'
            response_msg['data'] = book_ser.errors
        return Response(response_msg)

校驗:

def check_author(data):
    if data.startswith('sb'):
        raise ValidationError('作者名不能以sb開頭')


# 需要繼承Serializer
class BookSeralizer(serializers.Serializer):
    name = serializers.CharField(max_length=16, min_length=4)
    price = serializers.CharField()
    author = serializers.CharField(validators=[check_author])  # validators=[],列表中寫函式記憶體地址
    publish = serializers.CharField()

全部程式碼:

  • 1 表模型類
#models.py

from django.db import models

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=3)
    author = models.CharField(max_length=32)
    publish = models.CharField(max_length=32)
  • 2 序列化類
# -*- coding: UTF-8 -*- 
# @Date :2022/12/2 15:29

#ser.py

from rest_framework import serializers
from rest_framework.exceptions import ValidationError


def check_author(data):
    if data.startswith('sb'):
        raise ValidationError('作者名不能以sb開頭')


# 需要繼承Serializer
class BookSeralizer(serializers.Serializer):
    name = serializers.CharField(max_length=16, min_length=4)
    price = serializers.CharField()
    author = serializers.CharField(validators=[check_author])  # validators=[],列表中寫函式記憶體地址
    publish = serializers.CharField()

    # 區域性鉤子
    def validate_price(self, data):  # validate_欄位名,接受一個引數
        # print(type(data))
        # print(data)

        # 如果價格小於10,校驗不通過
        if float(data) < 10:
            # 校驗失敗,拋異常
            raise ValidationError('價格太低')
        return data

    def validate(self, validated_data):  # 全域性鉤子
        author = validated_data.get("author")
        publish = validated_data.get("publish")
        if author == publish:
            raise ValidationError("作者跟出版社一樣")
        return validated_data

    def update(self, instance, validated_data):
        # instance是Book這個物件
        # validated_data是校驗後的資料
        instance.name = validated_data.get('name')
        instance.price = validated_data.get('price')
        instance.author = validated_data.get("author")
        instance.publish = validated_data.get('publish')
        instance.save()  # book.save() 是django 的orm提供的
        return instance
  • 3 路由配置
#urls.py

from django.contrib import admin
from django.urls import path, re_path
from App import views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('books/(?P<pk>\d+)', views.BookView.as_view())
]
  • 4 書寫檢視類
#views.py

from django.shortcuts import render
from rest_framework.views import APIView
from App.models import Book
from App.ser import BookSeralizer
from rest_framework.response import Response  # drf提供的響應物件
from django.http import JsonResponse


class BookView(APIView):
    def get(self, request, pk):
        book_obj = Book.objects.filter(pk=pk).first()
        # 序列化誰,就把誰傳過來
        book_ser = BookSeralizer(book_obj)  # 呼叫類的__init__方法
        # 序列化物件.data就是序列化後的字典
        return Response(book_ser.data)
        # return JsonResponse(book_ser.data)

    def put(self, request, pk):
        response_msg = {'code': 100, 'msg': ''}
        # 找到要改的物件
        book_obj = Book.objects.filter(pk=pk).first()
        # 得到序列化類的物件
        # book_ser = BookSeralizer(book_obj, request.data)
        book_ser = BookSeralizer(instance=book_obj, data=request.data)
        # 要驗證(和forms元件校驗一樣)
        if book_ser.is_valid():  # 表示驗證通過
            book_ser.save()
            response_msg['msg'] = '資料校驗成功'
            response_msg['data'] = book_ser.data

        else:
            response_msg['code'] = 101
            response_msg['msg'] = '資料校驗失敗'
            response_msg['data'] = book_ser.errors
        return Response(response_msg)

4、reand_only和write_only

  • read_only
表明該欄位僅僅用於序列化輸出,預設False,
如果設定成True,postman中可以看到該欄位,修改時不需要傳該欄位
  • write_only
表明該欄位僅僅使用者反序列化輸入,預設False,
如果設定成了True,postman看不到該欄位,但修改時,該欄位必須傳

5、檢視所有,刪除,新增

  1. 查詢所有資料
path('books/', views.BooksView.as_view())

#views.py
重新寫一個檢視類
class BooksView(APIView):
    def get(self, request):
        response_msg = {'code': 100, 'msg': ''}
        books_obj = Book.objects.all()
        book_ser = BookSeralizer(books_obj, many=True)  # 序列化多條,如果序列化一條,不需要寫
        response_msg['data'] = book_ser.data
        response_msg['msg'] = '校驗成功'
        return Response(response_msg)

  1. 新增資料
# urls.py

path('books/', views.BooksView.as_view())


#views.py
class BooksView(APIView):
    # 新增資料
    def post(self, request):
        response_msg = {'code': 100, 'msg': '校驗成功'}
        # 修改才有instance,新增沒有,只有data
        book_ser = BookSeralizer(data=request.data)
        # book_ser = BookSeralizer(request.data) #按位置傳引數request.data,會給instance,就報錯了

        # 校驗資料
        if book_ser.is_valid():
            book_ser.save()
            response_msg['data'] = book_ser.data
        else:
            response_msg['code'] = 102
            response_msg['msg'] = '資料校驗失敗'
            response_msg['data'] = book_ser.errors
        return Response(response_msg)

#ser.py

#在序列化類中重寫create方法
    def create(self, validated_data):
        # Book.objects.create(name=validated_data.get('name'))
        instance = Book.objects.create(**validated_data)
        return instance
  1. 刪除資料
#urls.py
re_path('books/(?P<pk>\d+)', views.BookView.as_view()),


#views.py
class BookView(APIView):
    def delete(self, request, pk):
        book_obj = Book.objects.filter(pk=pk).delete()
        response_msg = {'code': 100, 'msg': '刪除成功'}
        return Response(response_msg)

6、自定義Response物件

# -*- coding: UTF-8 -*- 
# @Date :2022/12/2 19:30

#建立一個utils.py檔案 
class MyResponse():
    def __init__(self):
        self.code = 100
        self.msg = '成功'

    @property
    def get_dict(self):
        return self.__dict__

程式碼:

  • models.py
from django.db import models


# Create your models here.
class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=3)
    author = models.CharField(max_length=32)
    publish = models.CharField(max_length=32)
  • 序列化類
# -*- coding: UTF-8 -*- 
# @Date :2022/12/2 19:53
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from App.models import Book


def check_author(data):
    if data.startswith('sb'):
        raise ValidationError('作者不能以sb開頭')


class BookSerializer(serializers.Serializer):
    id = serializers.CharField(read_only=True)
    name = serializers.CharField(max_length=16, min_length=4)
    price = serializers.CharField(write_only=True)
    author = serializers.CharField(validators=[check_author])
    publish = serializers.CharField()

    def validate_price(self, data):
        if float(data) < 10:
            raise ValidationError('價格太低了')
        return data

    def validate(self, validate_data):
        author = validate_data.get('author')
        publish = validate_data.get('publish')
        if author == publish:
            raise ValidationError('作者和出版社一樣')
        return validate_data

    def update(self, instance, validated_data):
        instance.name = validated_data.get('name')
        instance.price = validated_data.get('price')
        instance.author = validated_data.get('author')
        instance.publish = validated_data.get('publish')
        instance.save()
        return instance

    def create(self, validated_data):
        instance = Book.objects.create(**validated_data)
        return instance
  • 自定義Response
# -*- coding: UTF-8 -*- 
# @Date :2022/12/2 20:12
class MyResponse:
    def __init__(self):
        self.code = 100
        self.msg = '檢驗成功'

    @property
    def get_dict(self):
        return self.__dict__


if __name__ == '__main__':
    res = MyResponse()
    res.data = {'name': 'zhao'}
    print(res.get_dict)

  • urls.py
from django.contrib import admin
from django.urls import path, re_path
from App import views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('book/(?P<pk>\d+)',views.BookView.as_view()),
    path('books/',views.BooksView.as_view())
]
  • 檢視類的書寫
from django.shortcuts import render
from rest_framework.views import APIView
from App.models import Book
from App.ser import BookSerializer
from rest_framework.response import Response
from App.utils import MyResponse


# Create your views here.
class BookView(APIView):
    # 獲取單個數據
    def get(self, request, pk):
        book_obj = Book.objects.filter(pk=pk).first()
        book_ser = BookSerializer(book_obj)
        return Response(book_ser.data)

    # 修改資料
    def put(self, request, pk):
        response = MyResponse()
        book_obj = Book.objects.filter(pk=pk).first()
        book_er = BookSerializer(instance=book_obj, data=request.data)
        if book_er.is_valid():
            book_er.save()
            response.data = book_er.data
            response.msg = '校驗成功'

        else:
            response.msg = '校驗失敗'
            response.code = 101
            response.data = book_er.errors
        return Response(response.get_dict)

    # 刪除資料
    def delete(self, request, pk):
        response = MyResponse()
        Book.objects.filter(pk=pk).delete()
        return Response(response.get_dict)


class BooksView(APIView):
    # 獲取所有資料
    def get(self, request):
        response = MyResponse()
        books_obj = Book.objects.all()
        book_er = BookSerializer(books_obj, many=True)
        response.data = book_er.data
        return Response(response.get_dict)

    # 新增資料
    def post(self, request):
        response = MyResponse()
        book_ser = BookSerializer(data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            response.data = book_ser.data
        else:
            response.data = book_ser.errors
            response.msg = '校驗失敗'
            response.code = 101
        return Response(response.get_dict)

7、模型類的序列化器

#ser.py 序列化類

class BookModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book  # 對應models.py中的模型
        fields = '__all__'  # 表示所有欄位都序列化
        # fields = ('name', 'price')  # 序列化指定欄位
        # exclude = ('name',)  # 除了name欄位,其他都序列化
        
        # 給authors和publish加write_only屬性
        # name加max_len屬性
        extra_kwargs = {
            'name': {'max_length': 8},
            'publish': {'write_only': True},
            'authors': {'write_only': True},
        }

#urls.py
path('books2/', views.BooksView2.as_view())
#views.py
from App.ser import BookModelSerializer
class BooksView2(APIView):
    def get(self, request):
        response = MyResponse()
        book_obj = Book.objects.all()
        book_ser = BookModelSerializer(book_obj, many=True)
        response.data = book_ser.data
        return Response(response.get_dict)

8、關鍵字many原始碼分析

# 序列化多條,需要傳many=True
path('many/',views.ManyView.as_view()),

class ManyView(APIView):
    def get(self, request):
        response = MyResponse()
        book_obj = Book.objects.filter().first()
        books_obj = Book.objects.all()
        book_ser = BookModelSerializer(book_obj)#序列化單條
        books_ser = BookModelSerializer(books_obj, many=True)#序列化多條
        print(type(book_ser))  # <class 'App.ser.BookModelSerializer'>
        print(type(books_ser))  
        # <class 'rest_framework.serializers.ListSerializer'>
        response.data = books_ser.data
        return Response(response.get_dict)
    
    
    #物件的生成---》先呼叫類的__new__方法,生成空物件
	#物件=類名(name=zhao),觸發類的__init__()
    #類的__new__方法控制物件的生成    
"""原始碼分析"""
class BaseSerializer(Field):
    def __new__(cls, *args, **kwargs):
        if kwargs.pop('many', False):
            return cls.many_init(*args, **kwargs)
        #沒有傳many=True,走下面,正常的物件例項化,
        return super().__new__(cls, *args, **kwargs)
    
    
    
     @classmethod
    def many_init(cls, *args, **kwargs):
        allow_empty = kwargs.pop('allow_empty', None)
        max_length = kwargs.pop('max_length', None)
        min_length = kwargs.pop('min_length', None)
        child_serializer = cls(*args, **kwargs)
        list_kwargs = {
            'child': child_serializer,
        }
        if allow_empty is not None:
            list_kwargs['allow_empty'] = allow_empty
        if max_length is not None:
            list_kwargs['max_length'] = max_length
        if min_length is not None:
            list_kwargs['min_length'] = min_length
        list_kwargs.update({
            key: value for key, value in kwargs.items()
            if key in LIST_SERIALIZER_KWARGS
        })
        meta = getattr(cls, 'Meta', None)
        list_serializer_class = getattr(meta, 'list_serializer_class', ListSerializer)
        return list_serializer_class(*args, **list_kwargs)

9、Serializer高階用法

新建立一個應用,記得一定要去註冊!

# 路由分發
from App2 import urls
 # path('App2/', include('App2.urls'))
 path('App2/', include(urls)),
#App2.等models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.IntegerField()
    pub_date = models.DateTimeField()
    publish = models.ForeignKey('Publish', on_delete=models.CASCADE, null=True)
    authors = models.ManyToManyField('Author')

    def __str__(self):
        return self.title


class Publish(models.Model):
    name = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    def __str__(self):
        return self.name

#App2.views.py

from django.shortcuts import render
from App2.models import Book
from App2.ser import BookSerializer
from rest_framework.views import APIView
from rest_framework.response import Response


class App2BookView(APIView):
    def get(self, request, pk):
        book_obj = Book.objects.filter(pk=pk).first()
        book_ser = BookSerializer(book_obj)
        return Response(book_ser.data)



# -*- coding: UTF-8 -*- 
# @Date :2022/12/3 16:27

#App2.ser.py
from rest_framework import serializers


class BookSerializer(serializers.Serializer):
    title123 = serializers.CharField(source='title')
    price = serializers.CharField()
    authors = serializers.CharField()
    publish = serializers.CharField(source='publish.email')  # 相當於book.publish.email
    pub_date = serializers.CharField()
# -*- coding: UTF-8 -*- 
# @Date :2022/12/3 16:27
from rest_framework import serializers


class BookSerializer(serializers.Serializer):
    title123 = serializers.CharField(source='title')
    price = serializers.CharField()
    # authors = serializers.CharField()
    authors = serializers.SerializerMethodField()  # 必須配一個方法,方法名叫get_欄位名,返回值就是要顯示的內容

    def get_authors(self, instance):
        # book物件
        authors = instance.authors.all()  # 取出所有作者
        l = []
        for author in authors:
            l.append({'name': author.name, 'age': author.age})
        return l

    publish = serializers.CharField(source='publish.email')  # 相當於book.publish.email
    pub_date = serializers.CharField()

source

# 可以改欄位名字
title123 = serializers.CharField(source='title')
# 可以.跨表

publish = serializers.CharField(source='publish.email')  # 相當於book.publish.email

# 可以執行方法
pub_date = serializers.CharField(source='test')  # test是Book表模型中

SerializerMethodField()

authors = serializers.SerializerMethodField()  # 必須配一個方法,方法名叫get_欄位名,返回值就是要顯示的內容

    def get_authors(self, instance):
        # book物件
        authors = instance.authors.all()  # 取出所有作者
        l = []
        for author in authors:
            l.append({'name': author.name, 'age': author.age})
        return l

10、回顧

#1.Serializer類,需要序列化什麼,必須寫一個繼承類,想要序列化什麼欄位,就在裡面寫欄位,(source)
#2 序列化queryset(列表)物件和真正的物件,many=True的作用,instance=要序列化的物件



#3 反序列化 instance=要序列化的物件,data=request.data
#4 欄位驗證,序列化類中,給欄位加屬性,區域性和全域性鉤子函式,欄位屬性validators=[check_author]
#5 當在檢視中呼叫, 序列化物件.is_valid()  booK_ser.is_valid(raise_exception=True) 只要驗證不通過,直接丟擲異常
#6 修改儲存---》呼叫序列化列物件.save(),重寫Serializer類 的update方法


		 def update(self, instance, validated_data):
            # instance是Book這個物件
            # validated_data是校驗後的資料
            instance.name = validated_data.get('name')
            instance.price = validated_data.get('price')
            instance.author = validated_data.get("author")
            instance.publish = validated_data.get('publish')
            instance.save()  # book.save() 是django 的orm提供的
            return instance
#7 序列化得到的欄位, 序列化物件.data
#8 自定義Response物件
    class MyResponse():
        def __init__(self):
            self.code = 100
            self.msg = '成功'

        @property
        def get_dict(self):
            return self.__dict__

    
 #9 反序列化的新增 序列化類(data=request.data),如果只傳了data,當呼叫序列化物件.save(),會觸發序列化類的create方法執行,當傳了instance和data時,呼叫 序列化物件.save(),會觸發序列化類的update方法執行

#10 重寫create方法,(可以很複雜)
	    def create(self, validated_data):
        instance = Book.objects.create(**validated_data)
        return instance
    
    
#11 ModelSerializer跟Model做了對應
	class BookModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = Book  # 對應models.py中的模型
            fields = '__all__'  # 表示所有欄位都序列化
            # fields = ('name', 'price')  # 序列化指定欄位
            # exclude = ('name',)  # 除了name欄位,其他都序列化,不能跟fields連用,寫誰,就排除誰

            # 給authors和publish加write_only屬性
            # name加max_len屬性
            extra_kwargs = {
                'name': {'max_length': 8},
                'publish': {'write_only': True},
                'authors': {'write_only': True,'max_lenth':6,'min_length':4},
            }
#12 如果在ModelSerializer中寫一個區域性鉤子或全域性鉤子,跟之前一摸一樣

#13 many=True能夠序列化多條的原因-----》__new__是在__init__之前執行的,造出了一個空物件

#14 介面:為了統一子類的行為