DRF框架serializer之ModelSerializer


一、基本語法

在沒有使用ModelSerializer序列化器類之前,我們定義的序列化器類都需要添加對應模型類字段的很多字段,如果添加的字段特別多,那么勢必會影響開發效率和代碼的可讀性,因此會選擇一種更為簡潔的序列化器類來幫我們優化框架代碼,簡化序列化器類中字段的創建

常規序列化器類示例:

from rest_framework import serializers
from rest_framework import validators
from .models import Projects


class ProjectSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=200, label="項目名稱", help_text='項目名稱',
                                 validators=[validators.UniqueValidator(queryset=Projects.objects.all(), message="項目名字段name必須唯一"),
                                             name_is_not_contain_x],)
    leader = serializers.CharField(max_length=50, label="項目負責人", help_text='項目負責人')
    programmer = serializers.CharField(max_length=50, label="開發人員", help_text="開發人員")
    tester = serializers.CharField(max_length=50, label="測試人員", help_text="測試人員")

使用ModelSerializer如下,已經簡化了很多代碼:

from rest_framework import serializers
from .models import Projects


class ProjectsModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = Projects
        fields = '__all__'

規則總結如下:

  • 需要在Meta類中使用model類屬性來指定需要按照哪一個模型類來創建
  • fields類屬性指定模型類中哪些字段需要輸入或輸出
  • 默認id主鍵會添加read_only=True
  • create_time和update_time會默認添加read_only=True
  • ModelSerializer類中自帶的有create和update方法,無需重寫即可生效

二、使用方法

直接使用ModelSerializer實例化的對象替換掉原先的序列化器類對象即可

from django.http import JsonResponse
from django.views import View
from django.db import connection
import json
from .models import Projects
from .serializers import ProjectsModelSerializer


class ProjectsPage(View):
    '''
    類視圖
    '''
    def post(self, request):

        input_data = json.loads(request.body)

        serializer_check_obj = ProjectsModelSerializer(data=input_data)

        if not serializer_check_obj.is_valid():
            return JsonResponse({"code": 1, "res": "error", "msg": serializer_check_obj.errors})

        serializer_check_obj.save()

        return JsonResponse(serializer_check_obj.validated_data, status=201)

二、反序列化校驗

1.默認全部字段輸出或輸入

在Meta子類中定義類屬性fields='__all__'

fields = '__all__'

2.指定需要輸出或輸入的字段

在Meta子類中定義類屬性fields=(字段1,字段2,......)

fields = ('name', 'leader', 'programmer')

3.排除不需要輸出或輸入的字段

在Meta子類中定義類屬性exclude=(字段1,字段2,......)

exclude = ('desc', )

4.只允許序列化輸出

在Meta子類中定義類屬性read_only_fields=(字段1,字段2,......)

read_only_fields = ('update_time', )

5.自定義校驗規則

1).在ModelSerializer類中創建字段類的對象

其優先級最高,如果以該類方式創建的方式很多,則應該選擇普通的序列化器類來定義

from rest_framework import serializers
from rest_framework import validators
from .models import Projects


class ProjectsModelSerializer(serializers.ModelSerializer):
    name = serializers.CharField(max_length=200, label="項目名稱", help_text='項目名稱',
                                 validators=[validators.UniqueValidator(queryset=Projects.objects.all(),
                                                                        message="項目名字段name必須唯一")], )

    class Meta:
        model = Projects
        fields = '__all__'

2).在Meta子類中定義extra_kwargs字段

鍵為字段名,值為一個字典,其中鍵為校驗項,值為校驗規則

from rest_framework import serializers
from rest_framework import validators
from .models import Projects


class ProjectsModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = Projects
        fields = '__all__'
        extra_kwargs = {
            'name': {
                'max_length': 50,
                'validators': [validators.UniqueValidator(queryset=Projects.objects.all(), message="項目名字段name必須唯一")]
            },
            'tester': {
                'max_length': 200
            }
        }

三、添加不在模型類里面而需要反序列化的字段

  • 定義字段
  • 添加字段名稱到ModelSerializer序列化器類Meta子類的fields屬性中
  • 在Meta子類中重寫create或者update方法
from rest_framework import serializers
from rest_framework import validators
from .models import Projects


def name_is_not_contain_x(value):
    if 'X' in value.upper():
        raise serializers.ValidationError("項目名字段name不能包含x的大小寫字符")


class ProjectsModelSerializer(serializers.ModelSerializer):

    email = serializers.EmailField(read_only=True)

    class Meta:
        model = Projects
        fields = ('id', 'name', 'leader', 'programmer', 'tester', 'create_time', 'update_time', 'email')
        extra_kwargs = {
            'name': {
                'max_length': 50,
                'validators': [validators.UniqueValidator(queryset=Projects.objects.all(), message="項目名字段name必須唯一"),
                               name_is_not_contain_x]
            },
            'tester': {
                'max_length': 200
            }
        }

    def validate_name(self, value):
        if '項目' in value:
            raise serializers.ValidationError("項目名稱name字段不能包含‘項目’字符")
        return value

    def validate(self, attrs):

        if 'A' in attrs.get('name') and 'B' in attrs.get('leader'):
            raise serializers.ValidationError("項目名稱字段name不包含A的同時項目負責人字段leader也不能包含B")
        return attrs

    def create(self, validated_data):
        validated_data.pop('email')

        return super().create(validated_data)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM