为什么Django admin尝试将字符串编码为ASCII而不是Unicode?这个错误是否与表面看起来不同?

3 投票
2 回答
3293 浏览
提问于 2025-04-15 17:38

我遇到了以下错误:

在 /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 个回答

3

如果有人对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)
7

我猜你是在让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字符串。

撰写回答