一、基本語法
在沒有使用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)