Django REST框架反序列化德文字符无效

2 投票
2 回答
1578 浏览
提问于 2025-04-18 10:50

我有一个这样的JSON字符串:

u'{"repeat_password":"password","password":"password","username":"üääöp","email":"püäöö@email.com"}'

然后我用以下代码处理它:

def deserialization_helper(json):
    stream = StringIO(unicode(json))
    return JSONParser().parse(stream)
#stuff...
serializer = ValidationSerializer(data=deserialization_helper(request.DATA['data']))

但是我发现出现了一个异常,只有在使用德语字符时会出现,如果我用普通的英语字符就没问题。

u'JSON parse error - \\'ascii\\' codec can\\'t encode characters in position 64-67: ordinal not in range(128)'

我把问题缩小到这一行代码:

JSONParser().parse(stream)

但我不知道怎么才能让它同时接受英语和德语字符。

任何帮助都非常感谢。

2 个回答

2

如果我们查看一下 JSONParser 的源代码(可以在这里找到:parsers.py):

def parse(self, stream, media_type=None, parser_context=None):
    """
    Parses the incoming bytestream as JSON and returns the resulting data.
    """
    parser_context = parser_context or {}
    encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET)

    try:
        data = stream.read().decode(encoding)
        return json.loads(data)
    except ValueError as exc:
        raise ParseError('JSON parse error - %s' % six.text_type(exc))

我们会发现,Django-Rest-Framework 期待接收到一个 字节流,然后用 Django 的 DEFAULT_CHARSET(通常是 UTF-8)来解码这个字节流。

如果不深入了解更多信息,很难给出解决方案:

  • request.DATA 已经被 DRF 的解析器处理过了,所以当数据完全是 JSON 格式时,没有必要再解析一次。
  • 如果你使用的是表单编码,或者 data 属性是一个包含 JSON 内容的字符串,你可以使用 force_bytes 将其转换为字节,或者直接使用 json.loads(这个方法可以接受 unicode)。
4

我也遇到过同样的问题。试着把这段代码放到你的settings.py文件里。

import sys
reload(sys)
sys.setdefaultencoding("utf-8")

撰写回答