2016-04-03 25 views
-1

當我sqlite3的數據庫中添加數據(非ASCII字符)作爲管理員,我得到了以下錯誤:爲什麼Django使用ascii而不是utf-8?

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 
+2

您確定您使用Python 2.7.10嗎?追溯說3.5 ... – Chris

+0

也許你正在打印到終端和終端有ascii編碼? – Bakuriu

+0

克里斯我不知道爲什麼它說2.7.10自創建項目我選擇python 3.5,回溯說同樣...可能是錯誤的起源? – Reygrip

回答

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 
+0

非常感謝你:) – Reygrip

+0

當然,這隻適用於Python 2.x?你能進一步解釋嗎? –

1

我幾乎沒有接近理解Python中的編碼繁瑣程序,但在試圖解碼這個錯誤我有點接近它。如果你只是想要正確的解決方案,跳到最後(提示:python_2_unicode_compatible)。

根據Porting to Python 3,在Python 可以兼得__str __()(其必須返回一個字節串/對象(類型 'STR'))和__unicode __()(它返回一個 '的unicode' 之一);但它應該是足夠的,如果你只有其中的一個:

print語句和str內置調用__str __()來確定一個對象的人類可讀表示。 unicode內置調用__unicode __()(如果存在),否則返回__str __()並用系統編碼解碼結果。相反,Model基類通過編碼爲UTF-8自動從__unicode __()派生__str __()。

Python 3中,在另一方面,有Unicode作爲默認的文字,只需要__str __(),提供了一個Unicode字符串,類型 'STR'(是的,相同的名稱,P2的字節字符串)。 Weeeeell,還有__bytes __(),但你可能永遠不需要它。

這是所有罰款和花花公子,直到走來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(encoding.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」(和字節字符串「字節」):

$ 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兼容,但是與Python 3斷開了,它需要__str __()。

定義__str__和__unicode__以返回self。名稱無論是哪種類型,似乎都適用於這兩種類型,但它肯定會在某個時候發生,正如你所發生的那樣,因爲人們不會檢查字符串類型(這對我來說有點令人費解)。您可以有一個__str__來檢查Python版本和字符串類型,並相應地傳遞或編碼該值,但Django人已經注意到了這一點:

Django改編的Python 2和3兼容庫 - Six 2 * 3,得到它) - 提供python_2_unicode_compatible,類裝飾器

別名__str__方法__unicode__和創建返回__unicode __()使用UTF-8編碼的結果的新__str__ 方法。

本教程(docs.djangoproject.com/en/1.9/intro/tutorial02/#playing-with-the-api - 對不起,不能讓更多的鏈接)的第2部分使用:

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 

Phew。所有這些,以及Ned Batchelder的Pragmatic Unicode(nedbatchelder.com/text/unipain.html),我想我已經開始掌握它了。儘管如此,我可能只是堅持Python 3 ...或PHP ...^_^

相關問題