升级到django-rest-framework 3后的UnicodeDecodeError

时间:2022-10-15 19:23:14

Under django-rest-framework 2, the following works fine:

在django-rest-framework 2下,以下工作正常:

from rest_framework import rest_response, generics
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer

class SomeView(generics.GenericAPIView):
    renderer_classes = JSONRenderer, BrowsableAPIRenderer

    def get(self, request, *args, **kwargs):
        ... 
        # Build a response dict with non-ascii in it
        ...
        return rest_response.Response(some_dict_with_non_ascii_in_it_somewhere)

I didn't have to explicitly encode any non-ascii...

我没有必要明确编码任何非ascii ...

However, after upgrading to DRF 3, the same code now throws the following error:

但是,升级到DRF 3后,相同的代码现在抛出以下错误:

Traceback (most recent call last):
  File "/Users/troy/.virtualenvs/publisher/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 63, in __call__
    return self.application(environ, start_response)
  File "/Users/troy/.virtualenvs/publisher/lib/python2.7/site-packages/whitenoise/base.py", line 119, in __call__
    return self.application(environ, start_response)
  File "/Users/troy/.virtualenvs/publisher/lib/python2.7/site-packages/django/core/handlers/wsgi.py", line 189, in __call__
    response = self.get_response(request)
  File "/Users/troy/.virtualenvs/publisher/lib/python2.7/site-packages/django/core/handlers/base.py", line 218, in get_response
    response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
  File "/Users/troy/.virtualenvs/publisher/lib/python2.7/site-packages/django/core/handlers/base.py", line 261, in handle_uncaught_exception
    return debug.technical_500_response(request, *exc_info)
  File "/Users/troy/.virtualenvs/publisher/lib/python2.7/site-packages/django_extensions/management/technical_response.py", line 5, in null_technical_500_response
    six.reraise(exc_type, exc_value, tb)
  File "/Users/troy/.virtualenvs/publisher/lib/python2.7/site-packages/django/core/handlers/base.py", line 164, in get_response
    response = response.render()
  File "/Users/troy/.virtualenvs/publisher/lib/python2.7/site-packages/django/template/response.py", line 158, in render
    self.content = self.rendered_content
  File "/Users/troy/.virtualenvs/publisher/lib/python2.7/site-packages/rest_framework/response.py", line 71, in rendered_content
    ret = renderer.render(self.data, media_type, context)
  File "/Users/troy/.virtualenvs/publisher/lib/python2.7/site-packages/rest_framework/renderers.py", line 104, in render
    separators=separators
  File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 250, in dumps
    sort_keys=sort_keys, **kw).encode(obj)
  File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 210, in encode
    return ''.join(chunks)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 671: ordinal not in range(128)

I'm guessing DRF 3 now has some new config value, somewhere, that was default under DRF 2. I've tried setting the REST_FRAMEWORK UNICODE_JSON setting to True, but I still get the same error...

我猜DRF 3现在有一些新的配置值,在某处,这是默认的DRF 2.我已经尝试将REST_FRAMEWORK UNICODE_JSON设置为True,但我仍然得到相同的错误...

Is there a setting that can make that piece behave as DRF 2 did? or does DRF 3 need me to hunt down the non-ascii character in my dictionary and manually encode it?

是否有一个可以使该片表现为DRF 2的设置?或者DRF 3是否需要我搜索字典中的非ascii字符并手动编码?

2 个解决方案

#1


12  

I found the answer.

我找到了答案。

In DRF 2, rest_framework.JSONRenderer.ensure_ascii is set to True. In DRF 3, rest_framework.JSONRenderer.ensure_ascii is set to not api_settings.UNICODE_JSON (I had missed the not there earlier, when I wrote the question...).

在DRF 2中,rest_framework.JSONRenderer.ensure_ascii设置为True。在DRF 3中,rest_framework.JSONRenderer.ensure_ascii被设置为不是api_settings.UNICODE_JSON(当我写这个问题时,我错过了之前的那个...)。

So to get it to behave like DRF 2, I needed to set the 'UNICODE_JSON' to False instead of True, like I had tried before (it is True by default):

所以为了让它像DRF 2一样,我需要将'UNICODE_JSON'设置为False而不是True,就像我之前尝试过的那样(默认为True):

REST_FRAMEWORK = {
    ...
    'UNICODE_JSON': False
}

Alternatively, I could, of course, encode my dictionary values, which in many cases could be the better option.

或者,我当然可以编码我的字典值,在许多情况下这可能是更好的选择。

#2


2  

By default Python 2.7 consider strings are binary. Try adding at the top of your files:

默认情况下,Python 2.7认为字符串是二进制。尝试在文件顶部添加:

from __future__ import unicode_literals

That will make your strings unicode by default and should help get them converted correctly.

这将使您的字符串默认为unicode,并且应该有助于正确转换它们。

#1


12  

I found the answer.

我找到了答案。

In DRF 2, rest_framework.JSONRenderer.ensure_ascii is set to True. In DRF 3, rest_framework.JSONRenderer.ensure_ascii is set to not api_settings.UNICODE_JSON (I had missed the not there earlier, when I wrote the question...).

在DRF 2中,rest_framework.JSONRenderer.ensure_ascii设置为True。在DRF 3中,rest_framework.JSONRenderer.ensure_ascii被设置为不是api_settings.UNICODE_JSON(当我写这个问题时,我错过了之前的那个...)。

So to get it to behave like DRF 2, I needed to set the 'UNICODE_JSON' to False instead of True, like I had tried before (it is True by default):

所以为了让它像DRF 2一样,我需要将'UNICODE_JSON'设置为False而不是True,就像我之前尝试过的那样(默认为True):

REST_FRAMEWORK = {
    ...
    'UNICODE_JSON': False
}

Alternatively, I could, of course, encode my dictionary values, which in many cases could be the better option.

或者,我当然可以编码我的字典值,在许多情况下这可能是更好的选择。

#2


2  

By default Python 2.7 consider strings are binary. Try adding at the top of your files:

默认情况下,Python 2.7认为字符串是二进制。尝试在文件顶部添加:

from __future__ import unicode_literals

That will make your strings unicode by default and should help get them converted correctly.

这将使您的字符串默认为unicode,并且应该有助于正确转换它们。