Django REST framework 中 Serializer 的使用

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 的字段与模型字段不一致

  1. 添加额外字段:你可以在MyModelSerializer中添加额外的字段,这些字段不需要与模型中的字段对应。这些字段可以用于临时存储前端发送的数据,然后在.save()方法中进行处理。

  2. 重命名字段:使用source参数在MyModelSerializer中重命名字段,这样你可以将前端使用的字段名映射到模型中的字段名。

  3. 自定义验证:在MyModelSerializer中重写validate_<field_name>方法,以提供自定义的验证逻辑。

  4. 使用partial参数:如果你只需要更新模型实例的部分字段,可以在调用.save()时使用partial=True参数。

  5. .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 的时候也不会报错了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值