我正在开发一个新的Django站点,并且在迁移了一堆数据之后,已经开始遇到令人沮丧的DjangoUnicodeDecodeError。有问题的坏人物是\ xe8(电子坟墓)。
有两个棘手的问题:
它只发生在生产服务器上,运行一个面向Apache的fcgi进程(在Django dev服务器上运行与相同数据库相同的代码没有问题)
有问题的堆栈跟踪完全在Django代码中。它在检索要显示的项目时发生在管理站点(也在其他地方),尽管实际上并未呈现包含错误字符的字段。
我甚至不完全确定从哪里开始调试,而不是尝试手动删除有问题的字符。我的猜测是,这是一个配置问题,因为它是特定于环境的,但我不知道从哪里开始。
编辑: 正如Daniel Roseman指出的那样,错误几乎肯定是在 unicode 方法中 - 或者更确切地说,是它调用的另一种方法。请注意,违规字符位于此处代码中未引用的字段中。我想在从db结果构建对象的方法中引发异常 - 如果从不评估查询集(例如,如果不是self.enabled)则没有错误。这是代码:
def get_blocking_events(self):
return Event.objects.filter(<get a set of events>)
def get_blocking_reason(self):
blockers = self.get_blocking_events()
label = u''
if not self.enabled:
label = u'Sponsor disabled'
elif len(blockers) > 0:
label = u'Pending follow-up: "{0}" ({1})'.format(blockers[0],blockers[0].creator.email)
if len(blockers) > 1:
label += u" and {0} other event".format(len(blockers)-1)
if len(blockers) > 2:
label += u"s"
return label
def __unicode__(self):
label = self.name
blocking_msg = self.get_blocking_reason()
if len(blocking_msg):
label += u" ({0})".format(blocking_msg)
return label
这是堆栈跟踪的尾部,为了好玩:
File "/opt/opt.LOCAL/Django-1.2.1/django/template/__init__.py", line 954, in render
dict = func(*args)
File "/opt/opt.LOCAL/Django-1.2.1/django/contrib/admin/templatetags/admin_list.py", line 209, in result_list
'results': list(results(cl))}
File "/opt/opt.LOCAL/Django-1.2.1/django/contrib/admin/templatetags/admin_list.py", line 201, in results
yield list(items_for_result(cl, res, None))
File "/opt/opt.LOCAL/Django-1.2.1/django/contrib/admin/templatetags/admin_list.py", line 138, in items_for_result
f, attr, value = lookup_field(field_name, result, cl.model_admin)
File "/opt/opt.LOCAL/Django-1.2.1/django/contrib/admin/util.py", line 270, in lookup_field
value = attr()
File "/opt/opt.LOCAL/Django-1.2.1/django/db/models/base.py", line 352, in __str__
return force_unicode(self).encode('utf-8')
File "/opt/opt.LOCAL/Django-1.2.1/django/utils/encoding.py", line 88, in force_unicode
raise DjangoUnicodeDecodeError(s, *e.args)
DjangoUnicodeDecodeError: 'utf8' codec can't decode bytes in position 956-958: invalid data. You passed in <Sponsor: [Bad Unicode data]> (<class 'SJP.alcohol.models.Sponsor'>)
答案 0 :(得分:1)
这里的问题是在 unicode 中使用以下行:
label += " ({0})".format(blocking_msg)
不幸的是,在python 2.x中,这是尝试将blocking_msg格式化为ascii字符串。你打算输入的是:
label += u" ({0})".format(blocking_msg)
答案 1 :(得分:1)
原来这可能是由于FreeTDS层连接到SQL Server。虽然FreeTDS为自动转换编码提供了一些支持,但我的设置要么配置错误,要么工作不正常。
我没有打这场战斗,而是暂时迁移到MySQL。