web-dev-qa-db-ja.com

UnicodeEncodeError: 'ascii'コーデックは文字をエンコードできません

ASCII以外の文字を含むファイルをアップロードすると、UnicodeEncodeErrorが発生します。

Exception Type: UnicodeEncodeError at /admin/studio/newsitem/add/
Exception Value: 'ascii' codec can't encode character u'\xf8' in position 78: ordinal not in range(128)

フルスタックトレース を参照してください。

MySQLとnginxとFastCGIでDjango 1.2を実行します。

これは Django Tracデータベース に従って修正される問題ですが、まだ問題があります。修正方法に関する提案は大歓迎です。

編集:これは私の画像フィールドです:

image = models.ImageField(_('image'), upload_to='uploads/images', max_length=100)
36
vorpyg

これをさらに調査した後、メインのNginx構成ファイルに文字セットを設定していないことがわかりました。

http {
  charset  utf-8;
}

上記を追加することで、問題はなくなり、私はこれがこの問題を処理する正しい方法だと思います。

12
vorpyg

Django with Supervisor で実行中にこの問題が発生した場合、ソリューションは、スーパーバイザーの構成のsupervisordセクションに以下を追加することです:

environment=LANG="en_US.utf8", LC_ALL="en_US.UTF-8", LC_LANG="en_US.UTF-8"

これにより、Debian Squeezeで実行されているSupervisor 3.0a8の問題が解決しました。

39
akaihola

Asciiのみを受け入れる場所(コンソールやパスなど)にUnicode文字列を表示する必要がある場合は、Python ascii以外の文字をベストエフォートに置き換えることを伝える必要があります。

>> problem_str = u'This is not all ascii\xf8 man'
>> safe_str = problem_str.encode('ascii', 'ignore')
>> safe_str
'This is not all ascii man'

Django templatingを慎重に処理することにより、エンコードの問題は管理者で防止されますが、カスタム列を追加し、値をasciiに変換するのを忘れた場合、またはstrモデルのメソッドでこれを忘れると、同じエラーが発生し、テンプレートのレンダリングができなくなります。

この文字列が(できればutf8)データベースに保存されていれば問題はありません。ASCII以外の文字を持つエンティティのタイトルを使用するファイルをアップロードしようとしているようです。

24
Lincoln B

これが役立つことを願っています。私の場合、daemontoolsを通じてDjangoを実行しています。

設定

export LANG='en_US.UTF-8'
export LC_ALL='en_US.UTF-8'

manage.pyを実行する前に実行スクリプトでアップロードファイル名の問題を解決しました

12

akaiholaの答えは役に立ちました。 upstartスクリプトで管理されたuWSGIでDjango appを実行する場合は、/ etc/init/yourapp.confにこれらの行を追加するだけです

env LANG="en_US.utf8"
env LC_ALL="en_US.UTF-8"
env LC_LANG="en_US.UTF-8"

それは私のために問題を解決しました。

10
PawelRoman

前述したように、これはロケールに関連しています。たとえば、gunicornを使用してDjango application、あなたはinit.dスクリプト(または、私としてはrunitスクリプト)、ここでロケールを設定できます。

ファイルのアップロードでUnicodeEncodeErrorを解決するには、export LC_ALL=en_US.UTF8アプリを実行するスクリプト内。

たとえば、これは私のものです(gunicornrunitを使用):

#!/bin/bash
export LC_ALL=en_US.UTF8
cd /path/to/app/projectname
exec gunicorn_Django -b localhost:8000 --workers=2

また、ビューでこれを使用して、テンプレートでロケールを確認できます。

import locale
data_to_tpl = {'loc': locale.getlocale(), 'lod_def': locale.getdefaultlocale()}

そしてただ表示{{loc}} - {{loc_def}}テンプレートに。

ロケール設定に関する詳細情報が得られます!それは私にとって非常に役に立ちました。

4
Exirel

コードの書き換えを回避する別の便利なオプションは、Pythonのデフォルトエンコーディングを変更することです。

virtualenv を使用している場合は、変更(または存在しない場合は作成)できますenv/lib/python2.7/sitecustomize.pyおよび追加:

import sys
sys.setdefaultencoding('utf-8')

または、運用システムにいる場合は、/usr/lib/python2.7/sitecustomize.py

4
Enric Mieza

もう少しコードを見ずに言うのは難しいですが、この質問に関連しているように見えます: nicodeDecodeError Djangoデフォルトのファイルベースのバックエンド

前述のDjangoチケットを見ると、「UnicodeEncodeErrorが発生した場合」のデプロイメントドキュメントに似たものに従う必要があるようです。
https://docs.djangoproject.com/en/1.4/howto/deployment/modpython/#if-you-get-a-unicodeencodeerror

(これはApache/mod_python用であることは知っていますが、ファイルシステムのエンコーディングがUTF-8ではないという同じ根本的な問題であり、nginxを使用するときに同様の修正があります)

編集:私はこのnginxモジュールが同等の修正になると言うことができるから: http://wiki.nginx.org/NginxHttpCharsetModule

4
Mark Lavin

Djangoおよびpython 2.7を使用している場合、これにより修正されます。

@python_2_unicode_compatible
class Utente(models.Model):

https://docs.djangoproject.com/en/dev/ref/utils/#Django.utils.encoding.python_2_unicode_compatible を参照してください

3
max4ever

python 2.7.8およびDjango 1.7を使用して、インポートすることで問題を解決しました:

_from __future__ import unicode_literals
_

force_text()を使用して:

_from Django.utils.encoding import force_text
_
3
daveoncode

このスレッドなどからの回答に基づいて...

ASCII=以外の文字を含むファイル名をアップロードしようとすると、genericpath.pyでUnicodeEncodeErrorが発生するという同じ問題がありました。

私はnginx、uwsgiとDjango with python 2.7。

すべてはローカルで正常に機能していましたが、サーバーでは機能していませんでした

ここに私が取った手順があります1. /etc/nginx/nginx.confに追加しました(問題を修正しませんでした)

http {
    charset utf-8;
}
  1. この行をetc/default/localeに追加しました(問題を修正しませんでした)

    LANGUAGE="en_US.UTF-8"

  2. 「成功」という見出しの下にリストされているここの指示に従いました https://code.djangoproject.com/wiki/ExpectedTestFailures (問題を修正しませんでした)

    aptitude install language-pack-en-base
    
  3. このチケット全体で見つかった https://code.djangoproject.com/ticket/17816 これは、ロケール情報で何が起きているかをサーバーのビューでテストすることを提案した

あなたの意見では

import locale
locales = "Current locale: %s %s -- Default locale: %s %s" % (locale.getlocale() + locale.getdefaultlocale())

テンプレートで

{{ locales }}

私にとっての問題は、Ubuntuサーバーにロケールもデフォルトロケールもありませんでしたが(ローカルOSX開発マシンにありました)、非ASCIIファイル名/パスpythonではUnicodeEncodeErrorが発生しますが、本番サーバーでのみ正しくアップロードされません。

ソリューション

これを自分のサイトとサイト管理者のuwsgi設定ファイルの両方に追加しました。/etc/uwsgi-emperor/vassals/my-site-config-iniファイル

env = LANG=en_US.utf8
2
lukeaus

答えはどれも私にはうまくいきませんでした(Django 1.10)でUbuntuでApacheを使用しました。

def remove_accents(value):
    nkfd_form = unicodedata.normalize('NFKD', str(value))
    return "".join([c for c in nkfd_form if not unicodedata.combining(c)])

uploaded_file = self.cleaned_data['data']

# We need to remove accents to get rid of "UnicodeEncodeError: 'ascii' codec can't encode character" on Ubuntu
uploaded_file.name = remove_accents(uploaded_file.name)
0
SaeX