为什么Django admin尝试将字符串编码为ASCII而不是Unicode?这个错误是否与表面看起来不同?
我遇到了以下错误:
在 /admin/results_cop/copsegmentresult/ 发生了模板语法错误
在渲染时捕获到一个异常: ('ascii', 'ISU欧洲花样滑冰锦标赛2009:女子单人滑:短节目 - 2. Susanna P\xc3\x96YKI\xc3\x96', 98, 99, '序号超出范围(128)')
无法渲染的字符串部分是:PÖYKIÖ
我不明白的是,为什么Django要把这个字符串当作ASCII来处理,而不是UTF-8呢?
编辑 1:
我忘了问 - 我也想知道怎么解决这个错误;)
编辑 2:
Bobince的回答是正确的 :) 我之前的代码大概是这样的:
def __unicode__(self):
return "%s %s" (self.foo, self.bar)
2 个回答
如果有人对bobince的回答感到困惑,可以这样理解:
模型中的字段已经是unicode格式了。
当你使用这样的unicode函数时:
def __unicode__(self):
return "{0}".format(self.field_one)
它实际上返回的是一个ASCII字符串(这意味着它会尝试把field_one转换成ASCII格式),如果field_one里面有ASCII以外的字符,就会出现上面提到的问题。
现在看看这个unicode函数:
def __unicode__(self):
return self.field_one
这个函数运行得很好,因为它直接返回unicode字符串,不需要进行转换。
让我们再看看第一个unicode函数,要让它正常工作,你只需要在前面加上u
,这样就变成了unicode字符串。
def __unicode__(self):
return u"{0}".format(self.field_one)
我猜你是在让Django处理一个字节字符串。这个字符串前面没有u
:
'ISU European Figure Skating Championships 2009: Senior Ladies Ladies: Short Program - 2. Susanna P\xc3\x96YKI\xc3\x96'
所以Django可能在尝试把它转换成页面的编码,通常是UTF-8。但是字节字符串不能直接编码;它们必须先变成Unicode字符串。Python本身会使用一个默认的编码来进行这个转换,通常是ascii
。
>>> 'P\xc3\x96YKI\xc3\x96'.encode('utf-8')
UnicodeDecodeError
所以你需要自己把这个字节字符串转换成Unicode字符串,方法是用UTF-8解码它,然后再发送到模板里。这个字符串是从哪里来的呢?通常你应该尽量保持应用程序中的所有内容字符串都是Unicode字符串。