【问题标题】:Django & Suds: UnicodeEncodeError When Using QuerySetsDjango & Suds:使用 QuerySet 时出现 UnicodeEncodeError
【发布时间】:2012-02-10 21:56:45
【问题描述】:

作为任何 Python 开发人员,我多年来一直在处理 Python 的 Unicode 问题。 但是现在我遇到了一个让我发疯的情况,我无法自己解决。 现在已经用了 1 天,包括 recherches ..

我的设置是一个小 Django 应用程序,它通过 SOAP(使用 Suds)连接到远程系统,提取一些数据并在 Django 的数据库中查找:

from myapp.models import Customer
client = suds.client.Client(...)
customer = client.service.getCustomerByEmail('foo@bar.com')

type(customer.email): <class 'suds.sax.text.Text'>

customer_exists = Customer.objects.filter(email=customer.email)

现在客户的电子邮件地址有一个德语变音 ü,这让 Django 引发如下异常:

Traceback (most recent call last):
  File "run_anatomy_client.py", line 19, in <module>
    print client.main()
  File "/Users/user/Documents/workspace/Wawi/application/myapp/client.py", line 282, in main
    if not Customer.objects.filter(email=customer.email.encode('latin1')):
  File "/Users/user/Documents/workspace/Wawi/application/myapp/client.py", line 76, in sync_customer
    if not customer_exists:
  File "/Users/user/Documents/workspace/Wawi/pyenv/lib/python2.7/site-packages/django/db/models/query.py", line 113, in __nonzero__
    iter(self).next()
  File "/Users/user/Documents/workspace/Wawi/pyenv/lib/python2.7/site-packages/django/db/models/query.py", line 107, in _result_iter
    self._fill_cache()
  File "/Users/user/Documents/workspace/Wawi/pyenv/lib/python2.7/site-packages/django/db/models/query.py", line 772, in _fill_cache
    self._result_cache.append(self._iter.next())
  File "/Users/user/Documents/workspace/Wawi/pyenv/lib/python2.7/site-packages/django/db/models/query.py", line 273, in iterator
    for row in compiler.results_iter():
  File "/Users/user/Documents/workspace/Wawi/pyenv/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 680, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/Users/user/Documents/workspace/Wawi/pyenv/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
    cursor.execute(sql, params)
  File "/Users/user/Documents/workspace/Wawi/pyenv/lib/python2.7/site-packages/django/db/backends/util.py", line 43, in execute
    logger.debug('(%.3f) %s; args=%s' % (duration, sql, params),
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 28: ordinal not in range(128)

我已经玩过encode()、decode(),修改了源文件的编码以及数据库布局,目前看起来如下:

mysql> show variables like '%character%';
+--------------------------+-----------------------------------------+
| Variable_name            | Value                                   |
+--------------------------+-----------------------------------------+
| character_set_client     | latin1                                  |
| character_set_connection | latin1                                  |
| character_set_database   | utf8                                    |
| character_set_filesystem | binary                                  |
| character_set_results    | latin1                                  |
| character_set_server     | latin1                                  |
| character_set_system     | utf8                                    |
| character_sets_dir       | /opt/local/share/mysql5/mysql/charsets/ |
+--------------------------+-----------------------------------------+
8 rows in set (0.00 sec)

奇怪的是——如果我设置一个跟踪点并在 Django shell 中执行完全相同的行,那么在使用 encode() 时它工作得很好:

(Pdb) Customer.objects.filter(email=customer.email)
*** UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 28:     ordinal not in range(128)
(Pdb) Customer.objects.filter(email=customer.email.encode('utf-8'))
[]

我会感谢任何提示..

【问题讨论】:

  • 嗨,你可以试试 unicode(customer.email, 'iso8859-1'),如果有帮助请告诉我...
  • 谢谢,但它没有:如果不是 Customer.objects.filter(email=unicode(customer.email, 'iso8859-1')): TypeError: 不支持解码 Unicode
  • 你能解决问题吗?看起来我也面临同样的问题

标签: python django suds


【解决方案1】:

suds.sax.text.Text 继承自 unicode

class Text(unicode):
    """
    An XML text object used to represent text content.
    @ivar lang: The (optional) language flag.
    @type lang: bool
    @ivar escaped: The (optional) XML special character escaped flag.
    @type escaped: bool
    """

如果你想使用,你可以只编码为 UTF-8。

email = customer.email.encode("utf-8")
customer_exists = Customer.objects.filter(email=email)

【讨论】:

  • 我认为最好使用 unicode(customer) 而不是 customer.encode('utf-8')
  • 我有完全同样的问题。非常感谢!
【解决方案2】:

我花了 2 个多小时试图弄清楚发生了什么,以及为什么在将 Suds 数据结构中的值分配给对象的字段后无法保存 Django 对象。

正如@guillaumevincent 提到的 Suds Text 类是从 unicode 继承的,并且实现不是 100% 正确,因此 Django 在尝试执行一些操作后失败,这将与基本 unicode 类型一起使用。

所以对于我会做的问题中的例子

customer_exists = Customer.objects.filter(email=unicode(customer.email))

就我而言,我也是这样做的

django_obj.field_name = suds_obj.field_name

希望这会为某人节省一些时间:)

【讨论】:

  • unicode() 未在 python 3 中定义。我的解决方案适用于 python 2.7 和 python 3。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-10
  • 2019-07-26
相关资源
最近更新 更多