Serializer 的作用:
它描述了如何将 Python 对象转换为 JSON 格式,以及如何将 JSON 数据转换为 Python 对象
Serializer 中提供了 save() 方法,可以将前端 POST 过来的数据保存到数据库中,当然需要验证一下数据,通过 is_valid() 方法完成。
save() 方法支持创建对象,也支持更新对象,如果是更新对象,需要将更新的对象作为 instance 参数传递给 save()
举个例子:
from rest_framework import serializers
from .models import MyModel
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = '__all__'
# 在视图中使用Serializer
def my_view(request):
if request.method == 'POST':
data = request.data
serializer = MyModelSerializer(data=data)
if serializer.is_valid():
serializer.save() # 调用.save()保存数据
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
前端 POST 的字段与模型字段不一致
-
添加额外字段:你可以在
MyModelSerializer
中添加额外的字段,这些字段不需要与模型中的字段对应。这些字段可以用于临时存储前端发送的数据,然后在.save()
方法中进行处理。 -
重命名字段:使用
source
参数在MyModelSerializer
中重命名字段,这样你可以将前端使用的字段名映射到模型中的字段名。 -
自定义验证:在
MyModelSerializer
中重写validate_<field_name>
方法,以提供自定义的验证逻辑。 -
使用
partial
参数:如果你只需要更新模型实例的部分字段,可以在调用.save()
时使用partial=True
参数。 -
在
.save()
方法中处理:在MyModelSerializer
的.save()
方法中,你可以手动处理前端上传的数据,并将其映射到模型字段。
class MyModelSerializer(serializers.ModelSerializer):
frontend_field_name = serializers.CharField(source='model_field_name') # 重命名字段
class Meta:
model = MyModel
fields = ['model_field_name', 'other_field']
def save(self, **kwargs):
# 处理前端上传的数据字段
if 'frontend_field_name' in self.validated_data:
self.validated_data['model_field_name'] = self.validated_data.pop('frontend_field_name')
# 如果有其他不需要映射到模型字段的额外数据,可以在这里处理
extra_data = self.validated_data.pop('extra_field', None)
# 调用父类的.save()方法保存数据
instance = super().save(**kwargs)
# 可以在这里处理额外的逻辑,例如将extra_data保存到其他地方
if extra_data:
# ...处理extra_data...
return instance
前端 POST 的字段,模型没有与之对应的字段,但是 save 又需要使用如何处理
可以在 Serializer 中包含额外字段,然后在 save 中通过 validated_data 处理,validated_data 中包含了前端模型中所有的字段以及你手动加的额外字段,你可以对额外的字段做其他的处理
class MyModelSerializer(serializers.ModelSerializer):
extra_field1 = serializers.CharField() # 前端上传的额外字段1
extra_field2 = serializers.CharField() # 前端上传的额外字段2
class Meta:
model = MyModel
fields = '__all__' # 或者列出模型中存在的字段
def save(self, **kwargs):
# 获取模型字段的数据
model_data = {key: value for key, value in self.validated_data.items() if key in self.Meta.fields}
# 获取额外字段的数据
extra_data = {key: value for key, value in self.validated_data.items() if key not in self.Meta.fields}
# 在这里处理额外的字段
# 例如,将extra_data存储在其它地方或进行其它操作
# 创建或更新模型实例
instance = super().save(**model_data)
# 可以在这里添加额外的逻辑,例如更新关联对象或执行其它操作
return instance
这些设置满足了前端到后端的数据字段的映射,但是 model 实例序列化为 JSON 的时候还需要做额外的操作,上面的 extra_field1,extra_field2 是模型中没有的,序列化 JSON 的时候就会报错,
可以做如下的处理:
class MyModelSerializer(serializers.ModelSerializer):
extra_field1 = serializers.CharField() # 前端上传的额外字段1
extra_field2 = serializers.CharField() # 前端上传的额外字段2
class Meta:
model = MyModel
fields = '__all__' # 或者列出模型中存在的字段
def save(self, **kwargs):
# 获取模型字段的数据
model_data = {key: value for key, value in self.validated_data.items() if key in self.Meta.fields}
# 获取额外字段的数据
extra_data = {key: value for key, value in self.validated_data.items() if key not in self.Meta.fields}
# 在这里处理额外的字段
# 例如,将extra_data存储在其它地方或进行其它操作
# 创建或更新模型实例
instance = super().save(**model_data)
# 可以在这里添加额外的逻辑,例如更新关联对象或执行其它操作
return instance
def to_representation(self, instance):
# 添加额外的字段
instance.extra_field1 = "value1"
instance.extra_field2 = "value2"
ret = super().to_representation(instance)
return ret
好了,这样就能直接通过 Serializer 的 save 保存数据,序列化 JSON 的时候也不会报错了