Skip to main content
 首页 » 编程设计

python之仅使用 __unicode__ 方法在 Django 模型上调用 str() 会返回特殊字符的不同编码

2024年08月29日39freeliver54

当在返回字段中带有特殊字符的 Django 模型对象上调用 str() 时,在这种情况下,字符 é 将返回为 \xc3\xa9 而不是预期的 \xe9。有什么问题?

我正在使用 Django 1.5.1 和 #coding=utf-8 和 from __future__ import unicode_literals as recommended in the django documentation .

我只实现了 __unicode__ 方法而不是 __str__ 方法作为 Django will use the __unicode__ method when calling str() .

这是一个代码示例(不是真正的生产代码)。

测试.py

# coding=utf-8 
from __future__ import unicode_literals 
from django.test import TestCase 
from unicodebug.models import MyModel 
 
 
class TestMyModel(TestCase): 
    def test_mymodel_str(self): 
        mymodel = MyModel(name='Chéri') 
        self.assertEqual(str(mymodel), 'Chéri') 
 
    def test_mymodel_unicode(self): 
        mymodel = MyModel(name='Chéri') 
        self.assertEqual(unicode(mymodel), 'Chéri') #  using unicode() works fine! 

模型.py

# coding=utf-8 
from __future__ import unicode_literals 
from django.db import models 
 
 
class MyModel(models.Model): 
    name = models.CharField(max_length=100) 
 
    def __unicode__(self): 
        return self.name 

运行测试时在终端输出。

(venv)frecon test$ python manage.py test unicodebug 
Creating test database for alias 'default'... 
/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py:501: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal 
  if not first == second: 
 
F. 
====================================================================== 
FAIL: test_mymodel_str (unicodebug.tests.TestMyModel) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
  File "unicodebug/tests.py", line 10, in test_mymodel_str 
    self.assertEqual(str(mymodel), 'Chéri') 
AssertionError: 'Ch\xc3\xa9ri' != u'Ch\xe9ri' 
 
---------------------------------------------------------------------- 
Ran 2 tests in 0.001s 
 
FAILED (failures=1) 
Destroying test database for alias 'default'... 

请您参考如下方法:

str() 必须对 unicode 值进行编码以生成 Pyton 字节字符串,它将使用默认编码 (sys.defaultencoding)。您必须明确地将后者设置为 UTF8,因为默认情况下它设置为 ASCII。

您看到的是模型返回的 Unicode 值的 UTF-8 编码。如果您希望测试通过,则必须解码该值以匹配您要与之比较的 Unicode 值,或者编码另一个值:

self.assertEqual(str(mymodel), 'Chéri'.encode('utf8')) 

或

self.assertEqual(str(mymodel).decode('utf8'), 'Chéri') 

简短演示:

>>> from __future__ import unicode_literals 
>>> b'Ch\xc3\xa9ri' == 'Chéri'.encode('utf8') 
True 
>>> b'Ch\xc3\xa9ri'.decode('utf8') == 'Chéri' 
True 

您可能想阅读有关 Python 和 Unicode 的内容: