ModelSerializer組件

ModelSerializer組件

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相同,但提供了:數據庫

  • 基於模型類自動生成一系列字段
  • 基於模型類自動爲Serializer生成validators,好比unique_together
  • 包含默認的create()和update()的實現

定義

好比咱們建立一個BookInfoSerializerpost

class BookInfoSerializer(serializers.ModelSerializer):
    """圖書數據序列化器"""
    class Meta:
        model = BookInfo
        fields = '__all__'
  • model 指明參照哪一個模型類
  • fields 指明爲模型類的哪些字段生成

咱們能夠在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)
相關文章
相關標籤/搜索