模特:
class ItemType(models.Model):
name = models.CharField(max_length=100)
def __unicode__(self):
logger.debug("1. Item Type %s created" % self.name)
return self.name
代码:
(...)
type = re.search(r"Type:(.*?)",text)
itemtype = ItemType.objects.create(name = name.group(1), defaults={'name':name.group(1)})
logger.debug("2. Item Type %s created" % name.group(1))
logger.debug("4. Item Type %s created" % itemtype.name)
logger.debug("3. Item Type %s created" % itemtype)
结果出乎意料(对我来说当然):
第一个logger.debug
按预期打印Item Type ąęńłśóć created
,但第二个引发错误:
DjangoUnicodeDecodeError: 'ascii' codec can't decode byte in position :
ordinal not in range(128).
You passed in <ItemType: [Bad Unicode data]> (<class 'aaa.models.ItemType'>)
为什么会出现错误,我该如何解决?
(文本是使用utf-8编码的html响应)
更新
我将调试添加到模型中,调试结果是:
2014-10-06 09:38:53,342 DEBUG views 2. Item Type ąęćńółśż created
2014-10-06 09:38:53,342 DEBUG views 4. Item Type ąęćńółśż created
2014-10-06 09:38:53,344 DEBUG models 1. Item Type ąęćńółśż created
2014-10-06 09:38:53,358 DEBUG models 1. Item Type ąęćńółśż created
那么为什么调试3.无法打印呢?
更新2 问题出在这里:
itemtype = ItemType.objects.create(name = name.group(1), defaults={'name':name.group(1)})
如果我把它改成
itemtype = ItemType.objects.create(name = name.group(1), defaults={'name':u'ĄĆĘŃŁÓŚ'})
一切都很好。
那么如何将其转换为unicode? unicode(name.group(1))不起作用。
答案 0 :(得分:3)
经过两天与自己的阴影相比,我找到了解决方案。对于这种情况,这不是一种解决方法,但思维的复杂变化,我必须重构整个代码。
我的假设是每个字符串都是UNICODE。如果不是 - 修复它。
不要使用“%s”或“某事”总是使用你的“%s”和你“cośtam”
:
class ItemType(models.Model):
name = models.CharField(max_length=100)
def save(self, *args, **kwargs):
if isinstance(self.name, str):
self.name=self.name.decode("utf-8")
super(ItemType, self).save(*args, **kwargs)
解释 - 如果某个名称填充了str而不是unicode - 将其更改为unicode。
我是如何找到这个的:
我想知道models.CharField中的文本是什么类型,并且发现,如果用unicode填充它 - 它是unicode,如果你填充 - str - 它是str。所以,如果你曾经用unicode“手”填充它,而在其他地方正则表达式用str填充它 - 结果是意外的。
unicode和str的最大问题是使用diactrics同时没有问题:
>>> text_str = "żółć"
>>> text_unicode = u"żółć"
>>> print text_str
żółć
>>> print text_uni
żółć
所以你看不出差异。
但是如果你使用其他命令:
>>> text_str
'\xc5\xbc\xc3\xb3\xc5\x82\xc4\x87'
>>> text_uni
u'\u017c\xf3\u0142\u0107'
差异很大。
如果有一些设置可以改变print(和similiars)的行为:
>>> print text_str
'\xc5\xbc\xc3\xb3\xc5\x82\xc4\x87'
>>> print text_uni
żółć
一切都会更容易调试 - 如果你能看到diactrics它没关系 - 如果没有 - 它很糟糕。
使用解码('utf-8')引导我找到解决方案:
>>> text_str
'\xc5\xbc\xc3\xb3\xc5\x82\xc4\x87'
>>> text_str.decode('utf-8')
u'\u017c\xf3\u0142\u0107'
>>> text_uni
u'\u017c\xf3\u0142\u0107'
VOILA!