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

如何处理JavaScript与Python DRF请求体JSON字段命名差异?

解决DRF与AngularJS命名规范不匹配的问题

这个问题我做前后端分离项目时也碰到过,确实挺闹心——毕竟JS的驼峰命名和Python的下划线命名是各自生态的标准,直接对接肯定会出现字段不匹配的情况。给你几个实用的解决思路,按需选择就行:


方法一:在DRF序列化器中自定义转换逻辑(最灵活)

自己写一个序列化器基类,处理下划线和驼峰的双向转换,其他业务序列化器继承这个基类就行,不用重复造轮子:

from rest_framework import serializers

class CamelCaseSerializer(serializers.ModelSerializer):
    def to_representation(self, instance):
        # 把Python下划线格式转成JS驼峰格式,返回给前端
        ret = super().to_representation(instance)
        camel_case_data = {}
        for key, value in ret.items():
            parts = key.split('_')
            # 比如 first_name → firstName
            camel_case_key = parts[0] + ''.join(part.capitalize() for part in parts[1:])
            camel_case_data[camel_case_key] = value
        return camel_case_data

    def to_internal_value(self, data):
        # 把前端传的驼峰格式转成Python下划线格式,存入后端
        snake_case_data = {}
        for key, value in data.items():
            snake_case_key = ''
            for char in key:
                # 比如 firstName → first_name
                if char.isupper():
                    snake_case_key += '_' + char.lower()
                else:
                    snake_case_key += char
            snake_case_data[snake_case_key] = value
        return super().to_internal_value(snake_case_data)

使用示例:你的用户序列化器直接继承这个基类

class UserSerializer(CamelCaseSerializer):
    class Meta:
        model = User
        fields = ('first_name', 'last_name')

这样前端传{"firstName": "Mangu Singh", "lastName": "Rajpurohit"}时,后端会自动转成first_name和last_name;返回数据时又会自动转回驼峰格式,完全不用改前后端业务代码。


方法二:用DRF第三方包快速解决(最省心)

有现成的第三方包djangorestframework-camel-case已经封装好了上述转换逻辑,安装配置后就能全局生效:

  1. 安装包
pip install djangorestframework-camel-case
  1. 在settings.py中配置DRF的渲染器和解析器
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'djangorestframework_camel_case.render.CamelCaseJSONRenderer',
        # 保留你原本需要的其他渲染器,比如BrowsableAPIRenderer
        'rest_framework.renderers.BrowsableAPIRenderer',
    ),
    'DEFAULT_PARSER_CLASSES': (
        'djangorestframework_camel_case.parser.CamelCaseJSONParser',
        'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser',
    ),
}

配置完成后,所有接口都会自动处理命名转换,适合中大型项目,不用手动写基类。


方法三:在AngularJS端通过拦截器处理

如果后端不想做改动,也可以在前端写一个HTTP拦截器,自动转换请求和响应的字段名:

// 自定义拦截器:处理命名格式转换
app.factory('namingConverterInterceptor', function() {
    // 驼峰转下划线
    function camelToSnake(str) {
        return str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
    }
    // 下划线转驼峰
    function snakeToCamel(str) {
        return str.replace(/_[a-z]/g, match => match[1].toUpperCase());
    }
    // 递归转换对象/数组的所有键
    function convertKeys(obj, converter) {
        if (typeof obj !== 'object' || obj === null) return obj;
        if (Array.isArray(obj)) return obj.map(item => convertKeys(item, converter));
        return Object.keys(obj).reduce((acc, key) => {
            acc[converter(key)] = convertKeys(obj[key], converter);
            return acc;
        }, {});
    }

    return {
        // 请求时:驼峰转下划线
        request: function(config) {
            if (config.data) config.data = convertKeys(config.data, camelToSnake);
            return config;
        },
        // 响应时:下划线转驼峰
        response: function(response) {
            if (response.data) response.data = convertKeys(response.data, snakeToCamel);
            return response;
        }
    };
});

// 注册拦截器
app.config(function($httpProvider) {
    $httpProvider.interceptors.push('namingConverterInterceptor');
});

这个方法适合前端团队更愿意主导格式转换的场景,后端完全不用做任何修改。


总结

个人最推荐方法二(第三方包),省心又高效;如果需要自定义一些特殊字段的转换逻辑,方法一更灵活;前端主导的话就用方法三。

内容的提问来源于stack exchange,提问作者Mangu Singh Rajpurohit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:36:59