02.Django REST framework - 序列化元件
序列化器-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('要刪的不存在')
""" 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新增或修改原有的選項引數 """
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
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() """
如果上方的說明還不清晰,可貼上到專案中執行。django版本2.2.2
僅演示方法,功能未完善不要在意
from rest_framework.serializers import ModelSerializer from rest_framework import serializers from app01 import models from rest_framework.exceptions import ValidationError class BookModelSerializer(ModelSerializer): class Meta(): model = models.Book fields = "__all__" # 需要跟表模型中寫的方法對應 publish_name = serializers.DictField() author_list = serializers.ListField() class AuthorDatailModelserializer(ModelSerializer): class Meta(): model = models.AuthorDetail fields = "__all__" class AuthorModelSerializer(ModelSerializer): class Meta(): model = models.Author fields = "__all__" # 第一種方法:source,只能選擇一個欄位 # author_detail = serializers.CharField(source='author_detail.birthday') # 第二種方法:SerializerMethodField,可多選 # author_detail = serializers.SerializerMethodField() # def get_author_detail(self, obj): # return {'p': obj.author_detail.telephone, 'b': obj.author_detail.birthday} # 第三種方法:在表模型中寫方法,需跟模型表models對應 # author_detail = serializers.DictField(source='author_detail_name') # 第四種方法:子序列化(Publishserializer需要在當前類上方提前定義好) # author_detail = AuthorDatailModelserializer() # def validate_name(self, data): # if data.startswith('sb'): # raise ValidationError('作者名不能有敏感詞彙') class PublishModelSerializer(ModelSerializer): class Meta(): model = models.Publish fields = "__all__" # def validate_name(self, data): # if data.startswith('sb'): # raise ValidationError('出版社名不能有敏感詞彙') 序列化類 serializer.py序列化類 serializer.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 {'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) # 表模型寫方法,展示更多欄位 def author_detail_name(self): return {'telephone':self.author_detail.telephone, 'birthday':self.author_detail.birthday, 'addr':self.author_detail.addr} 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 模型層 models.py模型層 models.py
from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path('admin/', admin.site.urls), # 查詢所有書籍,增加書籍 path('book/', views.BookView.as_view()), # 查詢,修改,刪除單本書籍 path('book/<int:pk>/', views.BookDetailView.as_view()), # 查詢所有作者,增加作者 path('author/', views.AuthorView.as_view()), # 查詢,修改,刪除單個作者 path('author/<int:pk>/', views.AuthorDetailView.as_view()), ] 路由層 urls.py路由層 urls.py
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.request import Request from app01 import serializer from app01 import models # 查詢所有書籍,增加書籍 class BookView(APIView): def get(self, request): books = models.Book.objects.all() ser = serializer.BookModelSerializer(instance=books, many=True) return Response(ser.data) def post(self, request): ser = serializer.BookModelSerializer(data=request.data) if ser.is_valid(): # 直接儲存,儲存到哪個表裡?需要重寫save ser.save() return Response(ser.data) return Response(ser.errors) # 查詢,修改,刪除單本書籍 class BookDetailView(APIView): def get(self, request, *args, **kwargs): book = models.Book.objects.filter(pk=kwargs.get('pk')).first() ser = serializer.BookModelSerializer(instance=book) print(ser.instance) return Response(ser.data) def put(self, request, *args, **kwargs): book = models.Book.objects.filter(pk=kwargs.get('pk')).first() ser = serializer.BookModelSerializer(instance=book, data=request.data) if ser.is_valid(): ser.save() return Response(ser.data) else: return Response('資料校驗有誤') def delete(self, request, *args, **kwargs): book = models.Book.objects.filter(pk=kwargs.get('pk')).delete() print(book) if book[0] > 0: return Response('') else: return Response('要刪的不存在') # 檢視所有作者,增加作者 class AuthorView(APIView): def get(self,request): author = models.Author.objects.all() ser = serializer.AuthorModelSerializer(instance=author,many=True) return Response(ser.data) def post(self,request): ser = serializer.AuthorModelSerializer(data=request.data) if ser.is_valid(): ser.save() return Response(ser.data) return Response(ser.errors) # 檢視單個作者。。。修改刪除功能未完善 class AuthorDetailView(APIView): def get(self,request, *args, **kwargs): author = models.Author.objects.filter(pk=kwargs.get('pk')).first() ser = serializer.AuthorModelSerializer(instance=author) return Response(ser.data) 檢視層 views.py檢視層 views.py
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的物件
入口 is_valid() 判斷_validated_data如果沒有 執行了 self.run_validation(self.initial_data) 目前在BaseSerializer,如果按住ctrl點選,會直接進到它父類的run_validation,進到Field,不是真正執行的方法 我們需要從頭找,實際上是Serializer類的run_validation 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, except (ValidationError, DjangoValidationError) as exc: raise ValidationError(detail=as_serializer_error(exc)) return value 區域性鉤子是在 to_internal_value執行的 def to_internal_value(self, data): for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) if validate_method is not None: validated_value = validate_method(validated_value)
序列化物件.data方法--呼叫父類data方法---呼叫物件自己的 to_representation(自定義的序列化類無此方法,去父類找) Serializer類裡有to_representation方法 for迴圈執行attribute = field.get_attribute(instance) 再去Field類裡去找get_attribute方法,self.source_attrs就是被切分的source 然後執行get_attribute方法,source_attrs 當引數傳過去,判斷是方法就加括號執行,是屬性就把值取出來
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相同,只是更換了更正確的名稱而已
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處理後的響應資料
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後整個後端邏輯