为什么DjangoJSONEncoder不处理代理对象?

时间:2015-06-11 09:22:11

标签: python json django

所以这是来自DjangoJSONEncoder的代码,它处理标准json编码器之外所需的大多数事情:

class DjangoJSONEncoder(json.JSONEncoder):
    """
    JSONEncoder subclass that knows how to encode date/time and decimal types.
    """
    def default(self, o):
        # See "Date Time String Format" in the ECMA-262 specification.
        if isinstance(o, datetime.datetime):
            r = o.isoformat()
            if o.microsecond:
                r = r[:23] + r[26:]
            if r.endswith('+00:00'):
                r = r[:-6] + 'Z'
            return r
        elif isinstance(o, datetime.date):
            return o.isoformat()
        elif isinstance(o, datetime.time):
            if is_aware(o):
                raise ValueError("JSON can't represent timezone-aware times.")
            r = o.isoformat()
            if o.microsecond:
                r = r[:12]
            return r
        elif isinstance(o, decimal.Decimal):
            return str(o)
        else:
            return super(DjangoJSONEncoder, self).default(o)

但是当它尝试编码代理对象时,它会失败并显示django.utils.functional.__proxy__ object at 0x7f53c6325ed0> is not JSON serializable

通过将DjangoJSONEncoder更改为:

,这很容易解决
from django.utils.functional import Promise
class DjangoJSONEncoder(json.JSONEncoder):
    """
    JSONEncoder subclass that knows how to encode date/time and decimal types.
    """
    def default(self, o):
        # See "Date Time String Format" in the ECMA-262 specification.
        if isinstance(o, datetime.datetime):
            r = o.isoformat()
            if o.microsecond:
                r = r[:23] + r[26:]
            if r.endswith('+00:00'):
                r = r[:-6] + 'Z'
            return r
        elif isinstance(o, datetime.date):
            return o.isoformat()
        elif isinstance(o, datetime.time):
            if is_aware(o):
                raise ValueError("JSON can't represent timezone-aware times.")
            r = o.isoformat()
            if o.microsecond:
                r = r[:12]
            return r
        elif isinstance(o, decimal.Decimal):
            return str(o)
        elif isinstance(o, Promise):  # Added these lines here 
            return unicode(o)
        else:
            return super(DjangoJSONEncoder, self).default(o)

但是写Django的人非常聪明。如果这是真正的解决方案,他们可能已经做到了。为什么他们没有这样做,那对unicode的调用,结合JSON编码使得这对DjangoJSONEncoder的错误修复?

我甚至在Django文档中找到了reference to this problem,所以它不像它不知道,我只是不明白为什么它不是默认值。

0 个答案:

没有答案