【问题标题】:Django issue : UnicodeEncodeErrorDjango 问题:UnicodeEncodeError
【发布时间】:2018-03-14 12:00:37
【问题描述】:

我的代码中出现了这个常见错误:

Exception Type: UnicodeEncodeError
Exception Value:'ascii' codec can't encode character u'\xe9' in position 6: ordinal not in range(128)

为什么?因为我正在处理带有法语口音的名字。

这是我的代码:

if 'rechercheGED' in request.GET:

        query_social_number = request.GET.get('q1social')

        sort_params = {}

        Individu_Recherche.set_if_not_none(sort_params, 'NumeroIdentification__iexact', query_social_number)

        query_lastname_list = Individu_Recherche.Recherche_Get(Individu, sort_params)

        lastname = query_lastname_list.Nom
        firstname = query_lastname_list.Prenom
        NIU = query_lastname_list.NumeroIdentification

        title = str(lastname + "_" + firstname + "_" + NIU)

问题来自:firstname = query_lastname_list.Prenom

因为在我的例子中,名字是Jérôme

我尝试了一些东西:

1) 在开头插入:

#-*- coding: utf-8 -*-
from __future__ import unicode_literals

2) 使用firstname = query_lastname_list.Prenom.encode('utf-8')firstname = query_lastname_list.Prenom.decode('utf-8')

但是到目前为止,不可能消除这个错误并处理带有重音符号的数据。

你有什么想法吗?

编辑:

这是完整的追溯:

Environment:


Request Method: GET
Request URL: http://localhost:8000/Identification/Person/Research/?q1social=19910-00001-634239-2&rechercheGED=Rechercher

Django Version: 1.10.3
Python Version: 2.7.12
Installed Applications:
['Institution',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'bootstrapform',
 'django_countries',
 'debug_toolbar',
 'chartit',
 'Configurations',
 'Home',
 'Authentication',
 'Identity',
 'rest_framework']
Installed Middleware:
['django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.middleware.gzip.GZipMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'debug_toolbar.middleware.DebugToolbarMiddleware',
 'DatasystemsCORE.middleware.OnlineNowMiddleware']



Traceback:

File "/usr/local/lib/python2.7/site-packages/django/core/handlers/exception.py" in inner
  39.             response = get_response(request)

File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _legacy_get_response
  249.             response = self._get_response(request)

File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/local/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  23.                 return view_func(request, *args, **kwargs)

File "/Users/valentinjungbluth/Desktop/Django/DatasystemsCORE/DatasystemsCore/DatasystemsCORE/Identity/views.py" in IdentityIndividuResearching
  454.         title = str(lastname + "_" + firstname + "_" + NIU)

Exception Type: UnicodeEncodeError at /Identification/Person/Research/
Exception Value: 'ascii' codec can't encode character u'\xe9' in position 6: ordinal not in range(128)

【问题讨论】:

  • 你用的是什么python和django版本?
  • Python 2.7 和 Django 1.10.3 ;)
  • 您不使用 Python 3 有什么原因吗?它具有更好的 Unicode 处理能力,Python 2 将在 2020 年结束生命周期。
  • 无,只是因为我3-4年前开始学习Python,是Python 2.X 有了Python 3就不会出现这种问题了?
  • 首先展示完整的traceback;我们甚至看不到错误发生在哪里。其次,展示您如何尝试“编码”和“解码”。 (第三,停止随机尝试添加编码声明或unicode_literals;两者都只适用于代码中的文字字符。)

标签: python django python-2.7 utf-8 ascii


【解决方案1】:

在 Python 3 中,您的 title = str(lastname + "_" + firstname + "_" + NIU) 会按照您的预期工作。在 Python 2 中,您将 Unicode 和 ASCII 混合在一起,因此 Python “有用地”尝试将 Unicode 字符串转换为 ASCII,以便将它们加在一起,当然,如果 Unicode 不能用 ASCII 表示,这将失败。

解决此问题的一种简单方法是将所有内容都设为 Unicode。例如,

firstname = u'Jérôme'
lastname = u'Pécresse'
title = lastname + u'_' + firstname
print title

输出

Pécresse_Jérôme

我强烈建议您迁移到 Python 3,一旦您习惯了对文本和字节的不同(但更出色)处理,它会让事情变得更加愉快。

同时,您可能会发现这篇文章对您有所帮助:Pragmatic Unicode,由 SO 资深人士 Ned Batchelder 撰写。

【讨论】:

  • 感谢您的回答!唯一的区别是我从我的数据库中挑选带有口音的数据,然后再进行一些处理。所以我不能写u'Jérôme',因为这个名字来自MyModel.FirstnameField
  • @Deadpool 明白了。如果 query_lastname_list.Nom 是一个实际的 Unicode 对象(它似乎来自您的 Traceback),那么我的代码仍然可以工作。然而,正如 Ned 在 Pragmatic Unicode 中解释的那样,在 Python 2 中,将所有内容编码为 UTF-8 并使用它通常更简单。
【解决方案2】:

由于您使用的是 Python 2.x,因此问题确实出在回溯的最后一行。

title = unicode(str(lastname + "_" + firstname + "_" + NIU))

lastnamefirstnameNIU 包含无法用 7 位 ASCII 表示的字符,这正是 str 所做的(在 Python 2 中)。

Django 为这些类型的字符串转换提供了有用的函数force_textforce_bytes,而且在做这种事情时使用字符串插值而不是+ 是一个好主意:

from django.utils.text import force_text

title = force_text('%s_%s_%s' % (lastname, firstname, NIU))

【讨论】:

  • 谢谢你,效果很好!多亏了你,我学会了一种新的方法来进行这种连接。我只有一个问题 - 如果我必须使用 Python 3.x,它的语法是否与 Python 2.x 相同?
  • 是的。 % 语法也适用于 3.x,但请务必查看 pyformat.info 以了解您可以做的所有事情:)
猜你喜欢
  • 2016-06-16
  • 2014-09-27
  • 1970-01-01
  • 2017-12-08
  • 2015-09-16
  • 2016-09-25
  • 2016-04-10
  • 2017-08-04
  • 1970-01-01
相关资源
最近更新 更多