序列化 => 後臺數據到前臺,反序列化 => 前臺數據寫到後臺數據庫
將類定義在一個類的內部,被定義的類就是內部類json
內部類及內部類的名稱空間,能夠直接被外部類訪問網絡
經過內部類的名稱空間,給外部類額外拓展一些特殊的屬性(配置),典型的Meta內部類 - 配置類app
class Book(model.Model): class Meta: db_model = "owen_book" # 配置自定義表名 class BookSerializer(serializers.ModelSerializer): class Meta: model = "Book" # 配置序列化類綁定的Model表
drf的響應類Response內部屬性有:post
class Response(SimpleTemplateResponse): def __init__(self, data=None, status=None, template_name=None, headers=None, exception=False, content_type=None):
data:響應的數據 - 空、字符串、數字、列表、字典、布爾ui
status:網絡狀態碼spa
template_name:drf本身也能夠支持先後臺不分離的返回頁面,可是不能和data共存(不會涉及到)rest
headers:響應頭code
exception:是否有異常響應(若是異常能夠賦值爲True,沒什麼用)對象
content_type:響應的結果類型(響應式data默認是application/json)
常見響應:
from rest_framework import status # 正常響應 Response( data={ 'status': 0, 'msg': 'ok', 'result': '正常數據' } ) # 異常響應 Response( data={ 'status': 1, 'msg': '客戶端錯誤提示', }, status=status.HTTP_400_BAD_REQUEST, exception=True )
序列化serializers類繼承的BaseSerializer類中初始化參數有如下的:
def __init__(self, instance=None, data=empty, **kwargs): pass
instance:是要被賦值對象的, - 對象類型數據賦值給instance
data:是被賦值數據的,- 請求來的數據賦值給data
kwargs:內部有三個屬性:many、partial、context
many:操做的對象或數據是單個或多個
partial:在修改需求時使用,能夠將全部的校驗字段required校驗規則設置爲False
context:用於視圖類和序列化類直接傳參使用
常見使用:
# 單查接口 UserModelSerializer(instance = user_obj) # 羣查接口 UserModelSerializer(instance = user_query, many=True) # 增接口 UserModelSerializer(data = request.data) # 總體改接口 UserModelSerializer(instance = user_obj, data = request.data) UserModelSerializer(instance = user_obj, data = requset.data, partial = True) # 刪接口用不到序列化類
class UserAPIView(APIView): def post(self, request, *args, **kwargs): # 單增 # 1)將前臺請求的數據交給序列化類處理 # 2)序列化類執行校驗方法,對前臺提交的全部數據進行數據校驗:校驗失敗就是異常返回,成功才能繼續 # 3)序列化組件完成數據入庫操做,獲得入庫對象 # 4)響應結果給前臺 serializer = serializers.UserModelSerializer(data=request.data) if serializer.is_valid(): # is_valid校驗 # 校驗成功 => 入庫 => 正常響應 obj = serializer.save() # save內部入庫 return Response({ 'status': 0, 'msg': 'ok', 'result': serializers.UserModelSerializer(obj).data # 新增的值返回 }, status=status.HTTP_201_CREATED) else: # 校驗失敗 => 異常響應 return Response({ 'status': 1, 'msg': serializer.errors, # errors錯誤信息 }, status=status.HTTP_400_BAD_REQUEST)
開發流程:
在models類中自定義字段,在serializer類中自定義寫字段
能夠在extra_kwargs中寫基礎的校驗規則,也能夠省略
制定局部鉤子與全局鉤子,全局鉤子在上述全部校驗後再校驗
一、不論是序列化仍是反序列化字段,都必須在field中進行聲明,沒有聲明的不會參與任何過程(數據會被丟棄)
二、用read_only 表示只讀,用write_only表示只寫,不標註二者默認表明便可讀也可寫
三、models類中的自定義的字段@property聲明的默認就是隻讀read_only
@property def gender(self): return self.get_sex_display()
四、自定義的只寫字段,在serializer類中須要本身手動聲明write_only,serializer中自定義的字段必須明確write_only不然會報錯,由於序列化會從model中強行反射自定義的字段,而model中沒有該字段就會報錯,而對於model中已經有的字段,在serializer類中再次聲明會對model原有的字段進行覆蓋,能夠不明確write_only表示可讀可寫,而且要寫在Meta上方同級的
re_password = serializers.CharField(write_only=True)
五、用extra_kwargs來爲寫的字段制定基礎校驗規則,能夠在extra_kwargs中使用required表明是否必須參與寫操做,有默認值和能夠爲空的時該值爲False,反之爲True,能夠手動修改
# 制定簡易基礎校驗規則查看有哪些規則 # serializers.DecimalField.max_value # serializers.CharField.max_length extra_kwargs = { 'name': { 'required': True, 'max_length': 32, 'error_messages': { # 能夠被國際化配置替代 'max_length': '太長' } } }
六、每個字段咱們均可以自定義校驗規則,使用局部鉤子 validate_字段名(self, value) 方法來自定義校驗規則,成功在返回value,失敗在拋出exceptions.ValidationError('異常信息')異常
七、咱們也可使用全局鉤子對好幾個字段進行校驗,好比password與re_password,使用validate(self, attrs),成功返回attrs,失敗則拋出異常exceptions.ValidationError('異常信息')
from rest_framework import serializers from . import models from rest_framework import exceptions # 制定簡易基礎校驗規則查看有哪些規則 # serializers.DecimalField.max_value # serializers.CharField.max_length class UserModelSerializer(serializers.ModelSerializer): # 自定義字段,覆蓋model中的字段,model中沒有則必須寫write_only=True pwd = serializers.CharField(max_length=8, min_length=4, write_only=True) re_pwd = serializers.CharField(max_length=8, min_length=4, write_only=True) class Meta: model = models.User # 將全部的字段都寫在fields中 fields = ['name', 'pwd', 'age', 'height', 'gender', 'img', 're_pwd'] # 自定義基礎的校驗規則 extra_kwargs = { 'name': { # 有默認值或者能夠爲空,咱們也能夠限制必須提供 'required': True, 'max_length': 8, 'error_messages': { # 能夠被國際化配置替代 'max_length': '太長' } } } # 局部與全局鉤子與Meta同級,屬性序列化類的 # 自定義單個字段校驗在局部鉤子中校驗,用validate_字段名(self, value) def validate_height(self, value): print(value) if value < 170: raise exceptions.ValidationError('過矮了') else: return value # 多字段之間校驗用全局鉤子,validate(self, attrs) attrs是字段值的字典 def validate(self, attrs): pwd = attrs.get('pwd') # 只拿出來校驗 re_pwd = attrs.pop('re_pwd') # 必須pop出來,不能存入數據庫中 if pwd != re_pwd: raise exceptions.ValidationError({'re_pwd': '兩次密碼不一致!'}) else: return attrs