在我的sqlite3数据库中以管理员身份添加数据(使用非ascii字符)时,出现以下错误:
Exception Type: UnicodeEncodeError at /admin/Project/vin/add/
Exception Value: 'ascii' codec can't encode character u'\xe2' in position 2:
ordinal not in range(128)
我无法弄清楚是什么问题,因为它在所有不同的设置中都写了utf-8 ......并且ascii只出现在错误中。
我得到了解释
Django Version: 1.9.4
Python Version: 2.7.10
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'Project']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
> Traceback:
> File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-pac
> kages/django/core/handlers/base.py" in get_response
> 149. response = self.process_exception_by_middleware(e, request)
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/core/handlers/base.py"
> in get_response
> 147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/contrib/admin/options.py"
> in wrapper
> 541. return self.admin_site.admin_view(view)(*args, **kwargs)
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/utils/decorators.py"
> in _wrapped_view
> 149. response = view_func(request, *args, **kwargs)
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/views/decorators/cache.py"
> in _wrapped_view_func
> 57. response = view_func(request, *args, **kwargs)
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/contrib/admin/sites.py"
> in inner
> 244. return view(request, *args, **kwargs)
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/contrib/admin/options.py"
> in add_view
> 1437. return self.changeform_view(request, None, form_url, extra_context)
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/utils/decorators.py"
> in _wrapper
> 67. return bound_func(*args, **kwargs)
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/utils/decorators.py"
> in _wrapped_view
> 149. response = view_func(request, *args, **kwargs)
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/utils/decorators.py"
> in bound_func
> 63. return func.__get__(self, type(self))(*args2, **kwargs2)
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/utils/decorators.py"
> in inner
> 184. return func(*args, **kwargs)
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/contrib/admin/options.py"
> in changeform_view
> 1382. self.log_addition(request, new_object, change_message)
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/contrib/admin/options.py"
> in log_addition
> 714. object_repr=force_text(object),
>
> File
> "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/django/utils/encoding.py"
> in force_text
> 80. s = six.text_type(bytes(s), encoding, errors)
vin模型
class Vin (models.Model):
nom_vin =models.CharField (max_length = 20)
millesime = models.IntegerField()
quantity = models.FloatField()
appelation = models.ForeignKey(Appelation)
def __str__(self):
return self.nom_vin
答案 0 :(得分:1)
尝试:
class Vin (models.Model):
nom_vin =models.CharField (max_length = 20)
millesime = models.IntegerField()
quantity = models.FloatField()
appelation = models.ForeignKey(Appelation)
def __unicode__(self): #You have __str__
return self.nom_vin
答案 1 :(得分:1)
我几乎不接近理解Python中的编码规则,但在尝试解码此错误时,我更接近它。如果您只是想要正确的解决方案,请跳到最后(提示:python_2_unicode_compatible
)。
根据Porting to Python 3,在Python 2 中,你可以同时拥有__str __()(必须返回字节字符串/对象(类型'str'))和__unicode __()(其中返回一个'unicode');但如果你只有一个就足够了:
另一方面,Python 3将unicode作为文字的默认值,只需要__str __(),提供一个unicode字符串,输入'str'(是的,与P2的字节字符串相同)。 Weeeeell,还有__bytes __(),但你可能永远都不需要它。print语句和str内置调用__str __()来确定对象的人类可读表示。 unicode内置调用__unicode __()(如果存在),否则返回__str __()并使用系统编码解码结果。相反,Model基类通过编码为UTF-8自动从__unicode __()派生__str __()。
这一切都很好,花花公子,直到来自encoding.py及其force_text
方法,管理界面使用:
def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
"""
Returns a text object representing 's' -- unicode on Python 2 and str on
Python 3. Treats bytestrings using the 'encoding' codec.
"""
[...]
try:
if not issubclass(type(s), six.string_types):
if six.PY3:
if isinstance(s, bytes):
s = six.text_type(s, encoding, errors)
else:
s = six.text_type(s)
elif hasattr(s, '__unicode__'):
s = six.text_type(s)
else:
s = six.text_type(bytes(s), encoding, errors)
错误在最后一行,我们只能用Python 2触发它(因为Python 3会触发if six.PY3
),当没有__unicode__方法时,我们正在使用unicode_literals(编码.py)确实如此)bytes()
(这只是str()
的别名)传递一个unicode对象,当它需要一个字节时:
$ python2
Python 2.7.11+ (default, Mar 30 2016, 21:00:42)
# Python 2 uses bytes (type "str") strings by default:
>>> bstr = 'â'
>>> type(bstr)
<type 'str'>
>>> bstr
'\xc3\xa2'
>>> bytes(bstr)
'\xc3\xa2'
# unicode_literals changes the default to unicode strings:
>>> from __future__ import unicode_literals
>>> ustr = 'â'
>>> type(ustr)
<type 'unicode'>
>>> ustr
u'\xe2'
# bytes() (str(), actually) expects a byte string, not unicode:
>>> bytes(ustr)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe2' in position 0: ordinal not in range(128) '
# We can encode ustr to bytes like so:
>>> bytes(ustr.encode('utf-8'))
'\xc3\xa2'
# Or with the equivalent b operator, for literals:
>>> bytes(b'â')
'\xc3\xa2'
# bstr has not changed:
>>> bytes(bstr)
'\xc3\xa2'
为了完整起见,Python 3的默认文字类型为unicode,但也称为'str'(字节字符串为'bytes'):
$ python3
Python 3.5.1+ (default, Jan 13 2016, 15:09:18)
>>> ustr='á'
>>> ustr
'á'
>>> type(ustr)
<class 'str'>
>>> bstr='á'.encode('utf-8')
>>> bstr
b'\xc3\xa1'
>>> type(bstr)
<class 'bytes'>
# Note that you can't use `b` to enconde a non-ascii literal
>>> bstr=b'á'
File "<stdin>", line 1
SyntaxError: bytes can only contain ASCII literal characters.
现在,您似乎正在运行Python 2.7,但使用的是3.5库!不知道你是怎么做到这一点的,但是按照Volodymyr的建议,你已经使你的代码与Python 2兼容了,但是需要__str __()的Python 3打破了。
定义__str__和__unicode__以返回self.name,无论它们被转换为哪种类型似乎都适用于两者,但它必然会破坏某些时间,就像你遇到的那样,因为人们不打扰检查字符串类型(这是对我来说有点令人费解)。您可以使用__str__检查Python版本和字符串类型,并相应地传递或编码该值,但Django人员已经处理过:
Django适应的Python 2和3兼容性库 - Six(那是2 * 3,得到它吗?) - 提供python_2_unicode_compatible
,一个类装饰器
将__str__方法别名为__unicode__并创建一个新的__str__ 返回以UTF-8编码的__unicode __()的结果的方法。
这在本教程的第2部分中使用(docs.djangoproject.com/en/1.9/intro/tutorial02/#playing-with-the-api - 抱歉,无法建立更多链接):
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible # only if you need to support Python 2
class Question(models.Model):
# ...
def __str__(self):
return self.question_text
呼。尽管如此,Ned Batchelder的实用Unicode(nedbatchelder.com/text/unipain.html),我想我已经开始了解它。不过,我可能会坚持使用Python 3 ...或PHP ...... ^ _ ^