1)序列化與反序列功能能夠整合成一個類,該類繼承ModelSerializer
2)繼承ModelSerializer類的資源序列化類,內部包含三部分
Meta子類、局部鉤子、全局鉤子
注:create和update方法ModelSerializer已經重寫了,使用不須要重寫
3)在Meta子類中:
用model來綁定關聯的Model類
用fields來設置全部的序列化反序列化字段
用extra_kwargs來設置系統的校驗規則
4)重要的字段校驗規則:
read_only校驗規則,表明該字段只參與序列化
write_only校驗規則,表明該字段只參與反序列化
required校驗規則,表明該字段在反序列化是是不是必填(True)仍是選填(False),不能和read_only一塊兒使用(規則衝突)
規則細節:
若是一個字段有默認值或是能夠爲空,沒設置required規則,默認爲False,反之默認值爲True
若是一個Model字段即沒有設置read_only也沒設置write_only,該字段默認參與序列化及反序列化
5)自定義序列化字段:在Model類中,定義方法屬性(能夠返回特殊值,還能夠完成連表操做),在序列化類的fields屬性中能夠選擇性插拔
6)自定義反序列化字段:在Serializer類中,自定義校驗字段,校驗規則也只能在聲明字段時設置,自定義的反序列化字段(如re_pwd),
必須設置write_only爲Truepython
from rest_framework.serializers import ModelSerializer from . import models # 整合序列化與反序列化 class UserModelSerializer(ModelSerializer): # 將序列化類與Model類進行綁定 # 設置序列化與反序列化全部字段(並劃分序列化字段與反序列化字段) # 設置反序列化的局部與全局鉤子 # 自定義反序列化字段,校驗規則只能在聲明自定義反序列化字段時設置,且必定是write_only re_pwd = serializers.CharField(min_length=3, max_length=64, write_only=True) class Meta: model = models.User # 序列化 fields = ['name', 'age', 'height', 'gender', 'pwd', 're_pwd'] # 反序列化 extra_kwargs = { 'name': { 'required': True, 'min_length': 3, 'error_messages': { 'min_length': '過短' } }, 'age': { 'required': True, # 數據庫有默認值或能夠爲空字段,required默認爲False 'min_value': 0 }, 'pwd': { 'required': True, 'write_only': True, # 只參與反序列化 }, 'gender': { 'read_only': True, # 只參與序列化 }, } def validate_name(self, value): if 'g' in value.lower(): raise serializers.ValidationError('名字中不能有g') return value def validate(self, attrs): pwd = attrs.get('pwd') re_pwd = attrs.pop('re_pwd') if pwd != re_pwd: raise serializers.ValidationError({'re_pwd': '兩次密碼不一致'}) return attrs # ModelSerializer已經幫咱們重寫了入庫方法
# 自定義插拔序列化字段:替換了在Serializer類中自定義的序列化字段(SerializerMethodField) # 自定義插拔序列化字段必定不參與反序列化過程 @property def gender(self): return self.get_sex_display()
from rest_framework.views import APIView from rest_framework.response import Response from . import models, serializers from rest_framework import status class UserV2APIView(APIView): # 單查羣查 def get(self, request, *args, **kwargs): pk = kwargs.get('pk') if pk: user_obj = models.User.objects.filter(pk=pk).first() if not user_obj: return Response({ 'status': 1, 'msg': '單查 error' }) # 完成序列化 user_data = serializers.UserModelSerializer(user_obj, many=False).data return Response({ 'status': 0, 'msg': '單查 ok', 'results': user_data }) # 羣查 user_query = models.User.objects.all() # 完成序列化 user_list_data = serializers.UserModelSerializer(user_query, many=True).data return Response({ 'status': 0, 'msg': '羣查 ok', 'results': user_list_data }) # 單增 def post(self, request, *args, **kwargs): request_data = request.data user_ser = serializers.UserModelSerializer(data=request_data) # 校驗失敗,直接拋異常,反饋異常信息給前臺,只要校驗經過,代碼纔會往下執行 result = user_ser.is_valid() if result: user_obj = user_ser.save() return Response({ 'status': 0, 'msg': 'ok', 'results': serializers.UserModelSerializer(user_obj).data }) else: # 校驗失敗,返回錯誤信息 return Response({ 'status': 1, 'msg': user_ser.errors }, status=status.HTTP_400_BAD_REQUEST)
若是咱們想要使用序列化器對應的是Django的模型類,DRF爲咱們提供了ModelSerializer模型類序列化器來幫助咱們快速建立一個Serializer類。shell
ModelSerializer與常規的Serializer相同,但提供了:數據庫
好比咱們建立一個BookInfoSerializerpost
class BookInfoSerializer(serializers.ModelSerializer): """圖書數據序列化器""" class Meta: model = BookInfo fields = '__all__'
咱們能夠在python manage.py shell中查看自動生成的BookInfoSerializer的具體實現ui
>>> from booktest.serializers import BookInfoSerializer >>> serializer = BookInfoSerializer() >>> serializer BookInfoSerializer(): id = IntegerField(label='ID', read_only=True) btitle = CharField(label='名稱', max_length=20) bpub_date = DateField(allow_null=True, label='發佈日期', required=False) bread = IntegerField(label='閱讀量', max_value=2147483647, min_value=-2147483648, required=False) bcomment = IntegerField(label='評論量', max_value=2147483647, min_value=-2147483648, required=False) image = ImageField(allow_null=True, label='圖片', max_length=100, required=False)
1) 使用fields來明確字段,__all__
表名包含全部字段,也能夠寫明具體哪些字段,如rest
class BookInfoSerializer(serializers.ModelSerializer): """圖書數據序列化器""" class Meta: model = BookInfo fields = ('id', 'btitle', 'bpub_date')
2) 使用exclude能夠明確排除掉哪些字段code
class BookInfoSerializer(serializers.ModelSerializer): """圖書數據序列化器""" class Meta: model = BookInfo exclude = ('image',)
3) 顯示指明字段,如:繼承
class HeroInfoSerializer(serializers.ModelSerializer): hbook = BookInfoSerializer() class Meta: model = HeroInfo fields = ('id', 'hname', 'hgender', 'hcomment', 'hbook')
4) 指明只讀字段圖片
能夠經過read_only_fields指明只讀字段,即僅用於序列化輸出的字段資源
class BookInfoSerializer(serializers.ModelSerializer): """圖書數據序列化器""" class Meta: model = BookInfo fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment') read_only_fields = ('id', 'bread', 'bcomment')
咱們可使用extra_kwargs參數爲ModelSerializer添加或修改原有的選項參數
class BookInfoSerializer(serializers.ModelSerializer): """圖書數據序列化器""" class Meta: model = BookInfo fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment') extra_kwargs = { 'bread': {'min_value': 0, 'required': True}, 'bcomment': {'min_value': 0, 'required': True}, } # BookInfoSerializer(): # id = IntegerField(label='ID', read_only=True) # btitle = CharField(label='名稱', max_length=20) # bpub_date = DateField(allow_null=True, label='發佈日期', required=False) # bread = IntegerField(label='閱讀量', max_value=2147483647, min_value=0, required=True) # bcomment = IntegerField(label='評論量', max_value=2147483647, min_value=0, required=True)