Django字符编码

时间:2010-11-06 18:12:17

标签: django utf-8

我正在开发一个新的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'>)

2 个答案:

答案 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。