一,基本语法
- 没有使用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实例化的对象替换掉原先的序列化器类对象即可 ```python 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)
<a name="NzLDs"></a>
# 三,反序列化校验
<a name="qNt2f"></a>
## 1,默认全部字段输入或者输出
在Meta子类中定义类属性fields='__all__'
```python
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)
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字段
- 键位字段名,值为一个字典,其中键位检验项,值为校验规则 ```python 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
}
}
<a name="pEa1E"></a>
# 四,添加不在模型类里面需要反序列化的字段
- 定义字段
- 添加字段名称到ModelSerializer序列化器类Meta子类的fields属性中
- 在Meta子类中重写create或者update方法
```python
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)