[Django REST framework - 序列化組件、source、鈎子函數]
序列化器-Serializer
什么是rest_framework序列化?
在寫前后端不分離的項目時:
我們有form組件幫我們去做數據校驗
我們有模板語法,從數據庫取出的queryset對象不需要人為去轉格式
當我們寫前后端分離項目的時:
我們需要自己去做數據校驗
我們需要手動去轉數據格式,因為跨平台數據傳輸都用json字符串,不能直接jsonqueryset對象
序列化器的作用
1 序列化:把python中的對象轉成json格式字符串
序列化器會把模型對象轉換成字典,經過response以后變成json字符串
2 反序列化:把json格式字符串轉成python中的對象
把客戶端發送過來的數據,經過request以后變成字典,序列化器可以把字典轉成模型
3 注意:drf的序列化組件(序列化器)
把對象(Book,queryset對象)轉成字典
因為有字典,直接丟到Response中就可以了
序列化,反序列化
-對象----》json
-json---》對象
序列化器
-定義一個類,繼承Serializer
-在類內些字段(常用字段,和非常用字段)(字段參數)
-在視圖類中,實例化得到一個序列化類的對象,傳入要序列化的數據
-對象.data---》就是字典
-source
序列化器的基本使用
from rest_framework.serializers import Serializer,ModelSerializer
from rest_framework import serializers
Serializer是rest_framework原生的序列化組件
ModelSerializer是rest_framework在原生的序列化組件的基礎上封裝了一層的序列化組件
用法:1、在用我們的rest_framework序列化組件的時候,我們的視圖層都必須寫視圖類,不能再寫視圖函數
2、我們需要針對每一張模型表寫一個類來繼承Serailizer或者ModelSerailizer類,
注:當我們在視圖類里需要對數據進行序列化或者反序列化的時候,在自己定義的類傳入需要序列化的數據實例化,
調用.data即可拿到序列化或者校驗后的數據了
Django REST framework中的Serializer使用類來定義,須繼承自rest_framework.serializers.Serializer
1 寫一個序列化的類,繼承Serializer
class BookSerializer(serializers.Serializer):
# 在這里寫要序列化的字段
# 序列化字段類(有很多,常用的就幾個,等同於models中的字段類)
# 字段類,有很多字段參數()
name = serializers.CharField()
price = serializers.IntegerField()
# publish = serializers.CharField()
2 在類中寫要序列化的字段(常用字段,和非常用字段)(字段參數)
name = serializers.CharField()
price = serializers.IntegerField()
3 在視圖類中使用(實例化得到一個序列化類的對象,傳入要序列化的數據)
class BookView(APIView):
def get(self, request):
book_list = models.Book.objects.all()
# instance=None, 要序列化的數據
# data=empty ,要反序列化的數據(目前data先不用)
# many=True 如果序列化多條,一定要寫many=True
book_ser = BookSerializer(instance=book_list, many=True)
# book_ser.data就是序列化后的數據
return Response(book_ser.data)
4 得到序列化后的數據,返回(對象.data---》就是字典)
book_ser.data
5 字段參數,source,指定要序列化表中的哪個字段
##########具體操作步驟見下方詳細操作#########
路由層 urls.py
from django.urls import path
from app import views
urlpatterns = [
path('admin/', admin.site.urls),
# 獲取所有的書籍信息
path('books_new/', views.BookView.as_view()),
# 對某本書進行操作
path('books_new/<int:id>/', views.BookViewId.as_view()),
]
模型層 models.py
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=32, verbose_name='書名')
publish = models.CharField(max_length=32, verbose_name='出版社')
price = models.IntegerField(verbose_name='價格')
序列化器層 serializer.py
from rest_framework import serializers
from app import models
# 新建序列化類,繼承Serializer
class BookSerializer(serializers.Serializer):
# 類中定義和模型表一一對應的字段,在這里寫要序列化的字段
# 序列化字段類(有很多,常用的就幾個,等同於models中的字段類)
# 字段類,有很多字段參數()
name = serializers.CharField()
price = serializers.IntegerField()
publish = serializers.CharField()
視圖層 views.py
# 獲取所有書籍信息
class BookView(APIView):
def get(self, request):
book_list = models.Book.objects.all()
book_ser = BookSerializer(instance=book_list, many=True)
# book_ser.data就是序列化后的數據
return Response(book_ser.data)
"""
instance=None, 要序列化的數據
data=empty ,要反序列化的數據(目前data先不用)
many=True 如果序列化多條,一定要寫many=True
"""
# 對某一本書進行操作
class BookViewId(APIView):
# 對某一個進行操作需要帶上id
def get(self, request, id):
book = models.Book.objects.all().filter(pk=id).first()
book_ser = BookSerializer(instance=book)
return Response(book_ser.data)
source
1 指定要序列化的字段(數據表中字段)
publish = serializers.CharField(source='publish.city') # 拿到出版社所在的城市
2 用的最多:只有一個字段(也可以跨表)
SerializerMethodField
用的最多:跨表查((來定制返回的字段)要么是列表,要么是字典)
publish=serializers.SerializerMethodField()
def get_publish(self,obj):
print(obj)
# return {'name':'sss','city':'sss'}
return {'name':obj.publish.name,'city':obj.publish.city,'email': obj.publish.email}
在模型表中寫方法
# models.py 表模型中寫的
class Book(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
publish_date = models.DateField()
publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
authors=models.ManyToManyField(to='Author')
def __str__(self):
return self.name
# def publish_name(self):
# return self.publish.name
def publish_name(self):
return {'name':self.publish.name,'city':self.publish.city}
@property
def author_list(self): # 列表推導式
return [{'name':author.name,'age':author.age,'id':author.nid} for author in self.authors.all()]
# serializers.py 序列化類中
class BookSerializer(serializers.Serializer):
name = serializers.CharField()
price = serializers.IntegerField()
publish_name = serializers.DictField()
author_list = serializers.ListField()
注意:serializer不是只能為數據庫模型類定義,也可以為非數據庫模型類的數據定義。serializer是獨立於數據庫之外的存在。
序列化類常用字段類型及屬性
字段參數針對性分類
# 針對charfield
max_length 最大長度
min_lenght 最小長度
allow_blank 是否允許為空
# 針對interfield
max_value 最小值
min_value 最大值
# 通用的,大家都有
# 這兩個最重要
read_only 表明該字段僅用於序列化輸出,默認False(序列化)
write_only 表明該字段僅用於反序列化輸入,默認False(反序列化)
required 表明該字段在反序列化時必須輸入,默認True
default 反序列化時使用的默認值
allow_null 表明該字段是否允許傳入None,默認False
error_messages 包含錯誤編號與錯誤信息的字典
validators 該字段使用的驗證器(了解)
反序列化,局部鈎子,全局鈎子
使用序列化器進行反序列化時,需要對數據進行驗證后,才能獲取驗證成功的數據或保存成模型類對象。
在獲取反序列化的數據前,必須調用is_valid()方法進行驗證,驗證成功返回True,否則返回False。
驗證失敗,可以通過序列化器對象的errors屬性獲取錯誤信息,返回字典,包含了字段和字段的錯誤。如果是非字段錯誤,可以通過修改REST framework配置中的NON_FIELD_ERRORS_KEY來控制錯誤字典中的鍵名。
驗證成功,可以通過序列化器對象的validated_data屬性獲取數據。
在定義序列化器時,指明每個字段的序列化類型和選項參數,本身就是一種驗證行為。
1 如果要反序列化,繼承了Serializer,必須重寫create方法
2 使用
# 視圖類
def post(self, request):
publish_ser = serializer.PublishSerializer(data=request.data)
if publish_ser.is_valid(): # 校驗數據
# 直接保存,保存到哪個表里?需要重寫save
publish_ser.save()
return Response(publish_ser.data)
else:
print(publish_ser.errors)
return Response('數據有問題啊')
# 序列化類
def create(self, validated_data):
# 校驗過后的數據
res = models.Publish.objects.create(**validated_data)
return res
"""
父類的save內部調用了create,所以我們重寫create
return res 給了self.instance以后,instance就有值了
publish_ser.data,instance就有值調用data就能拿到序列化后的數據
is_valid()方法還可以在驗證失敗時拋出異常serializers.ValidationError,可以通過傳遞raise_exception=True參數開啟,
REST framework接收到此異常,會向前端返回HTTP 400 Bad Request響應。
"""
局部和全局鈎子
# validate_字段名
def validate_name(self, data):
# data就是當前字段的值
if data.startswith('sb'):
raise ValidationError('不能以sb開頭')
else:
return data
# 在序列化器中需要同時對多個字段進行比較驗證時,可以定義validate方法來驗證
def validate(self, attrs):
if attrs.get('name') == attrs.get('city'):
raise ValidationError('city和名字不能一樣')
else:
return attrs
模型類序列化器
如果我們想要使用序列化器對應的是Django的模型類,DRF為我們提供了ModelSerializer模型類序列化器來幫助我們快速創建一個Serializer類
ModelSerializer與常規的Serializer相同,但提供了:
- 基於模型類自動生成一系列字段
- 基於模型類自動為Serializer生成validators,比如unique_together
- 包含默認的create()和update()的實現
視圖類 views.py
class BookView(APIView):
def get(self,request):
qs=models.Book.objects.all()
ser=serializer.BookModelSerializer(instance=qs,many=True)
return Response(ser.data)
def post(self,request):
ser = serializer.BookModelSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response(ser.data)
else:
return Response(ser.errors)
class BookDetailView(APIView):
def get(self,request,id):
book = models.Book.objects.filter(pk=id).first()
ser = serializer.BookModelSerializer(instance=book)
return Response(ser.data)
def put(self,request,id):
book = models.Book.objects.filter(pk=id).first()
ser = serializer.BookModelSerializer(instance=book,data=request.data)
if ser.is_valid():
ser.save()
return Response(ser.data)
else:
return Response(ser.errors)
def delete(self,request,id):
res = models.Book.objects.filter(pk=id).delete()
if res[0] > 0:
return Response('')
else:
return Response('要刪的不存在')
序列化類 serializers.py
"""
ModelSerializer
使用步驟:
1、新建序列化類,繼承ModelSerializer
2、類中定義和模型表一一對應的字段,這里可以定義class Meta() 然后指定模型表model和 映射字段fields,比Serializer更簡潔
-其中類中的名字可以改變,需要在serializers.CharField()的括號中指定source=某個字段,建議映射關系
-外鍵關系的字段可以用serializers.SerializerMethodField(),需要在下方固定寫 get_字段名 的方法,
這里可以寫具體邏輯,最終返回結果就是該字段的結果
3、當新增數據的時候不需要重寫父類的create方法,這里ModelSerializer做了封裝
4、當修改數據的時候不需要重寫父類的update方法,這里ModelSerializer做了封裝
5、當完成這些配置后就可以在視圖類中實例化調用了,序列化的時候序列化,反序列化的時候校驗
"""
from rest_framework import serializers
from app import models
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book # model 指明參照哪個模型類
fields = '__all__' # fields 指明為模型類的哪些字段生成,__all__表名包含所有字段
# 給字段類加屬性
extra_kwargs = {
'publish': {'required': True, 'write_only': True},
'authors': {'required': True, 'write_only': True},
}
publish_detail = PublishSerializer(source='publish',read_only=True)
author_list=serializers.ListField(read_only=True)
# 字段自己的校驗,全局鈎子,局部鈎子
"""
使用fields來明確字段,__all__表名包含所有字段,也可以寫明具體哪些字段,如
使用exclude可以明確排除掉哪些字段
使用extra_kwargs參數為ModelSerializer添加或修改原有的選項參數
"""
表模型 models.py
這是完整的模型表,上面的視圖和序列化類只展示了部分表的增刪改查演示
from django.db import models
class Book(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32, verbose_name='書名')
price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='價格')
publish_date = models.DateField(verbose_name='出版時間')
publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
authors=models.ManyToManyField(to='Author')
class Meta:
verbose_name_plural = '書籍表'
def __str__(self):
return self.name
# 表模型寫方法,展示更多字段
# def publish_name(self):
# return self.publish.name
# def publish_name(self):
# return {'name':self.publish.name,'city':self.publish.city}
#
# @property
# def author_list(self):
# return [{'name':author.name,'age':author.age,'id':author.nid} for author in self.authors.all()]
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32, verbose_name='名字')
age = models.IntegerField(verbose_name='年齡')
author_detail = models.OneToOneField(to='AuthorDetail',to_field='nid',unique=True,on_delete=models.CASCADE)class Meta:
verbose_name_plural = '作者表'
def __str__(self):
return self.name
class AuthorDetail(models.Model):
nid = models.AutoField(primary_key=True)
telephone = models.BigIntegerField(verbose_name='電話')
birthday = models.DateField(verbose_name='生日')
addr = models.CharField(max_length=64, verbose_name='地址')
class Meta:
verbose_name_plural = '作者詳情表'
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32, verbose_name='社名')
city = models.CharField(max_length=32, verbose_name='地址')
email = models.EmailField(verbose_name='郵箱')
class Meta:
verbose_name_plural = '出版社表'
def __str__(self):
return self.name
路由urls.py
urlpatterns = [
path('books/',views.BookView.as_view()),
path('books/<int:id>/',views.BookDetailView.as_view()),
]
序列化高級用法
ModelSerializer用的基本就是下面這個方法
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = "__all__"
"""
如果想讓字段更豐富些,可以采用任意一種方法實現(方法有很多種)
第一種方法:source
publish = serializers.CharField(source='publish.city')
第二種方法:SerializerMethodField
publish=serializers.SerializerMethodField()
def get_publish(self,obj):
return {'name':obj.publish.name,'city':obj.publish.city,'email': obj.publish.email}
第三種方法:在表模型寫方法
def publish_name(self):
return {'name':self.publish.name,'city':self.publish.city}
@property
def author_list(self):
return [{'name':author.name,'age':author.age,'id':author.nid} for author in self.authors.all()]
第四種方法:子序列化
publish = Publishserializer()
"""
序列化類源碼分析
many參數
1 序列化類實例化的時候,傳了many,序列化多條,不傳,就序列化單條
# many=True,實例化得到的對象是ListSerializer
ser=serializer.BookModelSerializer(instance=qs,many=True)
print(type(ser))
# rest_framework.serializers.ListSerializer
# 列表中套了很多BookModelSerializer
# many=False,實例化得到的對象是BookModelSerializer
ser=serializer.BookModelSerializer(instance=book)
print(type(ser))
# app01.serializer.BookModelSerializer
類實例化:在執行__init__之前,先執行了__new__生成一個空對象(決定了是哪個類的對象)
在__new__中進行判斷,如果many=True,就返回ListSerializer的對象
局部全局鈎子的源碼分析
# 入口是 ser.is_valid(),是BaseSerializer的方法
# 最核心的代碼
self._validated_data = self.run_validation(self.initial_data) # 切記不要按住ctrl點
# run_validation 調用的是Serializer類的方法
def run_validation(self, data=empty):
value = self.to_internal_value(data) # 局部鈎子的代碼
try:
self.run_validators(value)
value = self.validate(value) # 全局鈎子的執行
assert value is not None, '.validate() should return the validated data'
except (ValidationError, DjangoValidationError) as exc:
raise ValidationError(detail=as_serializer_error(exc))
return value
# 局部鈎子核心代碼
for field in fields:
validate_method = getattr(self, 'validate_' + field.field_name, None) #反射字段的局部鈎子方法
try:
if validate_method is not None:
validated_value = validate_method(validated_value) #執行局部鈎子方法
except ValidationError as exc:
errors[field.field_name] = exc.detail
except DjangoValidationError as exc:
errors[field.field_name] = get_error_detail(exc)
序列化對象.data
序列化對象.data方法--調用父類data方法---調用對象自己的
to_representation(自定義的序列化類無此方法,去父類找)
Serializer類里有to_representation方法
for循環執行attribute = field.get_attribute(instance)
再去Field類里去找get_attribute方法,self.source_attrs就是被切分的source
然后執行get_attribute方法,source_attrs
當參數傳過去,判斷是方法就加括號執行,是屬性就把值取出來
請求與響應
請求對象 Request
REST framework 傳入視圖的request對象不再是Django默認的HttpRequest對象,而是REST framework提供的擴展了HttpRequest類的Request類的對象。
REST framework 提供了Parser解析器,在接收到請求后會自動根據Content-Type指明的請求數據類型(如JSON、表單等)將請求數據進行parse解析,解析為類字典[QueryDict]對象保存到Request對象中。
****Request對象的數據是自動根據前端發送數據的格式進行解析之后的結果。**
無論前端發送的哪種格式的數據,我們都可以以統一的方式讀取數據。
常用屬性
1).data
request.data 返回解析之后的請求體數據。類似於Django中標准的request.POST和 request.FILES屬性,但提供如下特性:
包含了解析之后的文件和非文件數據
包含了對POST、PUT、PATCH請求方式解析后的數據
利用了REST framework的parsers解析器,不僅支持表單類型數據,也支持JSON數據
2).query_params
request.query_params與Django標准的request.GET相同,只是更換了更正確的名稱而已
響應對象 Response
REST framework提供了一個響應類Response
,使用該類構造響應對象時,響應的具體數據內容會被轉換(render渲染)成符合前端需求的類型。,
REST framework提供了Renderer
渲染器,用來根據請求頭中的Accept
(接收數據類型聲明)來自動轉換響應數據到對應格式。如果前端請求中未進行Accept聲明,則會采用默認方式處理響應數據,我們可以通過配置來修改默認響應格式。
可以在rest_framework.settings查找所有的drf默認配置項
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': ( # 默認響應渲染類
'rest_framework.renderers.JSONRenderer', # json渲染器
'rest_framework.renderers.BrowsableAPIRenderer', # 瀏覽API渲染器
)
}
data
數據不要是render處理之后的數據,只需傳遞python的內建類型數據即可,REST framework會使用renderer
渲染器處理data
。
**data
不能是復雜結構的數據,如Django的模型類對象,對於這樣的數據我們可以使用Serializer
序列化器序列化處理后(轉為了Python字典類型)再傳遞給data
參數。**
參數說明:
#一直會用
data: 為響應准備的序列化處理后的數據(字典)
#偶爾會用
headers: 用於存放響應頭信息的字典;
status: 狀態碼,默認200;(http請求的狀態碼)
# 基本不用
template_name: 模板名稱,如果使用HTMLRenderer 時需指明;
content_type: 響應數據的Content-Type,通常此參數無需傳遞,REST framework會根據前端所需類型數據來設置該參數。
常用屬性
1).data
傳給response對象的序列化后,但尚未render處理的數據
2).status_code
狀態碼的數字
3).content
經過render處理后的響應數據
所有http狀態碼
為了方便設置狀態碼,REST framewrok在rest_framework.status模塊中提供了常用狀態碼常量。
1)信息告知 - 1xx
HTTP_100_CONTINUE = 100
HTTP_101_SWITCHING_PROTOCOLS = 101
2)成功 - 2xx
HTTP_200_OK = 200
HTTP_201_CREATED = 201
HTTP_202_ACCEPTED = 202
HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203
HTTP_204_NO_CONTENT = 204
HTTP_205_RESET_CONTENT = 205
HTTP_206_PARTIAL_CONTENT = 206
HTTP_207_MULTI_STATUS = 207
HTTP_208_ALREADY_REPORTED = 208
HTTP_226_IM_USED = 226
3)重定向 - 3xx
HTTP_300_MULTIPLE_CHOICES = 300
HTTP_301_MOVED_PERMANENTLY = 301
HTTP_302_FOUND = 302
HTTP_303_SEE_OTHER = 303
HTTP_304_NOT_MODIFIED = 304
HTTP_305_USE_PROXY = 305
HTTP_306_RESERVED = 306
HTTP_307_TEMPORARY_REDIRECT = 307
HTTP_308_PERMANENT_REDIRECT = 308
4)客戶端錯誤 - 4xx
HTTP_400_BAD_REQUEST = 400
HTTP_401_UNAUTHORIZED = 401
HTTP_402_PAYMENT_REQUIRED = 402
HTTP_403_FORBIDDEN = 403
HTTP_404_NOT_FOUND = 404
HTTP_405_METHOD_NOT_ALLOWED = 405
HTTP_406_NOT_ACCEPTABLE = 406
HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407
HTTP_408_REQUEST_TIMEOUT = 408
HTTP_409_CONFLICT = 409
HTTP_410_GONE = 410
HTTP_411_LENGTH_REQUIRED = 411
HTTP_412_PRECONDITION_FAILED = 412
HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413
HTTP_414_REQUEST_URI_TOO_LONG = 414
HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416
HTTP_417_EXPECTATION_FAILED = 417
HTTP_418_IM_A_TEAPOT = 418
HTTP_422_UNPROCESSABLE_ENTITY = 422
HTTP_423_LOCKED = 423
HTTP_424_FAILED_DEPENDENCY = 424
HTTP_426_UPGRADE_REQUIRED = 426
HTTP_428_PRECONDITION_REQUIRED = 428
HTTP_429_TOO_MANY_REQUESTS = 429
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451
5)服務器錯誤 - 5xx
HTTP_500_INTERNAL_SERVER_ERROR = 500
HTTP_501_NOT_IMPLEMENTED = 501
HTTP_502_BAD_GATEWAY = 502
HTTP_503_SERVICE_UNAVAILABLE = 503
HTTP_504_GATEWAY_TIMEOUT = 504
HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505
HTTP_506_VARIANT_ALSO_NEGOTIATES = 506
HTTP_507_INSUFFICIENT_STORAGE = 507
HTTP_508_LOOP_DETECTED = 508
HTTP_509_BANDWIDTH_LIMIT_EXCEEDED = 509
HTTP_510_NOT_EXTENDED = 510
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511
#drf推薦的寫法
return Response(ser.data,status.HTTP_200_OK)
drf 整體內容概述
0 drf是django的一個app
-序列化器
-Request
-Response
-版本控制
-認證,頻率,權限
-過濾,排序,分頁
-視圖相關
-自動生成接口文檔(coreapi,swagger)
-jwt做認證(第三方)
-xadmin---》對admin的美化(bootstrap+jq,1.x版本),simple-ui
-RBAC:基於角色的訪問控制(公司內部項目)
1 序列化器
1. 序列化,序列化器會把模型對象轉換成字典,經過response以后變成json字符串
2. 反序列化,把客戶端發送過來的數據,經過request以后變成字典,序列化器可以把字典轉成模型
3. 反序列化,完成數據校驗功能
2 Serializer
-序列化
-實例化序列化對象,many參數作用
-source
-SerializerMethodField
-模型表中寫方法
-反序列化
-ser=BookSerializer(data=request.data)
-數據校驗:ser.is_valid()
-存數據:手動存,重寫BookSerializer的create方法,update方法
-ser.save() 如果是新增,會調用create,如果是修改,會調用update
-ser.data 如果有instance對象,就是對instance做序列化
-全局,局部鈎子,字段參數
3 ModelSerializer
-class Meta:
model=Book
fields=‘__all__’
extra_kwargs
-重寫某個字段:跟之前學的又一樣了
-子序列化
4 常用非常用字段
5 字段參數
6 如果第三張表是手動建的,authors是存不進去的
{
name:ddd
price:10
publish:1
authors:[1,2]
}
7 請求對象的屬性
8 響應對象
-data:響應數據
-status:響應狀態碼
-header:響應頭
-content_type:響應類型
9 加入serializer后整個后端邏輯