You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST Framework如何仅通过序列化器实现反序列化键名映射

解决方案

完全不需要在视图层修改request.data,所有键名映射逻辑都可以收敛到序列化器内部实现,最推荐的实现方式是重写序列化器的to_internal_value方法,符合DRF原生设计逻辑,没有额外侵入性。


具体实现

to_internal_value是DRF反序列化流程的第一入口,原生职责就是把客户端传入的原始字典,转换成后续校验、存库使用的标准结构化数据,在这一步做键名转换不会影响后续的字段校验、模型写入、响应序列化逻辑。

修改后的序列化器代码如下:

class NameSerializer(serializers.HyperlinkedModelSerializer):
    # 德英字段映射表,后续新增映射直接在这里加即可
    FIELD_KEY_MAP = {
        "vorname": "firstname",
        "nachname": "lastname",
        # 如果你要兼容首字母大写的入参格式,补上这两行即可
        # "Vorname": "firstname",
        # "Nachname": "lastname",
    }

    def to_internal_value(self, data):
        converted_data = {}
        for raw_key, value in data.items():
            # 命中映射规则就替换成英文字段名,未命中的保留原键,交给原生校验逻辑处理
            target_key = self.FIELD_KEY_MAP.get(raw_key, raw_key)
            converted_data[target_key] = value
        # 转换完成后交给父类原生方法走后续校验流程
        return super().to_internal_value(converted_data)

    class Meta:
        model = Name
        fields = ["firstname", "lastname"]

改完之后视图层可以删掉所有手动改键的代码,还原成最简洁的标准写法即可:

@api_view(['POST'])
@parser_classes([JSONParser])
def convert(request):
    serializer = NameSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_200_OK)  
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

方案优势

  • 映射规则统一维护在序列化器内部,和视图层完全解耦,后续调整字段映射不需要改视图逻辑
  • 完全兼容DRF原生的字段校验、模型存库、响应序列化逻辑,接口返回的JSON键名仍然是要求的firstname/lastname
  • 扩展灵活,后续如果需要兼容其他命名规则的入参、或者支持序列化输出德文字段名,只需要在序列化器内加对应转换逻辑即可。比如要支持GET请求返回德文字段,只要重写to_representation方法做反向键名映射就行。

不推荐用字段source参数实现这个需求:因为你的模型字段是英文名,用source指定德文字段名后,存库时DRF会尝试给模型不存在的德文字段赋值,需要额外重写create/update方法修正键名,反而增加冗余代码。

内容的提问来源于stack exchange,提问作者Thabb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 15:48:16