2012-02-09 20 views
6

私の質問はhereと似ていますが、提案された解決策は私には役に立たない。私はDjango管理アプリケーションを介して 'Testaråäö.txt'というファイルをアップロードしようとしています。Djangoの管理者にファイルをアップロードする際にUnicodeEncodeErrorが発生する

私はDebian 6サーバでGunicorn 0.13.4とNginx 0.7.6.7を使ってDjango 1.3.1を実行しています。データベースはPostgreSQL 8.4.9です。他のUnicodeデータは問題なくデータベースに保存されるので、問題は何とかファイルシステムにあるはずです。

私はnginx.confに

http { 
    charset utf-8; 
} 

を設定しました。 LC_ALLとLANGは 'sv_SE.UTF-8'に設定されています。 'locale'を実行するとこれが確認されます。私はちょうどロケールが正しく設定されていることを確認するために、私のnginxのinitスクリプトでLC_ALLとLANGを設定しようとしました。

Traceback (most recent call last): 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/core/handlers/base.py", line 111, in get_response 
response = callback(request, *callback_args, **callback_kwargs) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/contrib/admin/options.py", line 307, in wrapper 
return self.admin_site.admin_view(view)(*args, **kwargs) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/utils/decorators.py", line 93, in _wrapped_view 
response = view_func(request, *args, **kwargs) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/views/decorators/cache.py", line 79, in _wrapped_view_func 
response = view_func(request, *args, **kwargs) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/contrib/admin/sites.py", line 197, in inner 
return view(request, *args, **kwargs) 

File "/srv/django/letebo/app/cms/admin.py", line 81, in change_view 
return super(PageAdmin, self).change_view(request, obj_id) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/utils/decorators.py", line 28, in _wrapper 
return bound_func(*args, **kwargs) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/utils/decorators.py", line 93, in _wrapped_view 
response = view_func(request, *args, **kwargs) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/utils/decorators.py", line 24, in bound_func 
return func(self, *args2, **kwargs2) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/transaction.py", line 217, in inner 
res = func(*args, **kwargs) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/contrib/admin/options.py", line 985, in change_view 
self.save_formset(request, form, formset, change=True) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/contrib/admin/options.py", line 677, in save_formset 
formset.save() 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/forms/models.py", line 482, in save 
return self.save_existing_objects(commit) + self.save_new_objects(commit) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/forms/models.py", line 613, in save_new_objects 
self.new_objects.append(self.save_new(form, commit=commit)) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/forms/models.py", line 717, in save_new 
obj.save() 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/base.py", line 460, in save 
self.save_base(using=using, force_insert=force_insert, force_update=force_update) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/base.py", line 504, in save_base 
self.save_base(cls=parent, origin=org, using=using) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/base.py", line 543, in save_base 
for f in meta.local_fields if not isinstance(f, AutoField)] 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/fields/files.py", line 255, in pre_save 
file.save(file.name, file, save=False) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/db/models/fields/files.py", line 92, in save 
self.name = self.storage.save(name, content) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/core/files/storage.py", line 48, in save 
name = self.get_available_name(name) 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/core/files/storage.py", line 74, in get_available_name 
while self.exists(name): 

File "/srv/.virtualenvs/letebo/lib/python2.6/site-packages/django/core/files/storage.py", line 218, in exists 
return os.path.exists(self.path(name)) 

File "/srv/.virtualenvs/letebo/lib/python2.6/genericpath.py", line 18, in exists 
st = os.stat(path) 

UnicodeEncodeError: 'ascii' codec can't encode characters in position 52-54: ordinal not in range(128) 

UPDATE:

は、ここでトレースバックだ私はオンになってデバッグでGunicornを実行しようとした、と全く問題のないファイルのアップロード。これは問題がNginxであることを意味するはずです。それでも私はどこを見ているのですか。

Gunicorn:

HTTP/1.1 302 FOUND 
Server: gunicorn/0.13.4 
Date: Thu, 09 Feb 2012 14:50:27 GMT 
Connection: close 
Transfer-Encoding: chunked 
Expires: Thu, 09 Feb 2012 14:50:27 GMT 
Vary: Cookie 
Last-Modified: Thu, 09 Feb 2012 14:50:27 GMT 
Location: http://my-server.se:8000/admin/cms/page/15/ 
Cache-Control: max-age=0 
Content-Type: text/html; charset=utf-8 
Set-Cookie: messages="yada yada yada"; Path=/ 

nginxの:それはどんな意味がある場合はここでGunicornとnginxの、からの生のレスポンスヘッダがある

HTTP/1.1 500 INTERNAL SERVER ERROR 
Server: nginx/0.7.67 
Date: Thu, 09 Feb 2012 14:50:57 GMT 
Content-Type: text/html; charset=utf-8 
Transfer-Encoding: chunked 
Connection: close 
Vary: Cookie 

500 
+0

を取得したのですか?どうやってガンコーンを始めたの? – ashwoods

+0

申し訳ありません。私は解決策が見つかるまでユニコード文字の使用を避けるようにクライアントに指示しました(別のサーバーに移行するように見えます)。私はSupervisorを使ってガンコンを起動しています。 –

+0

これも私たちのために起こります。同じ設定 - NginX、スーパーバイザー、GunicornがDjangoアプリを実行しています。私はそれを修正しようと2時間を無駄にし、インターネット上のすべての推奨事項を幸運なしに試しました。うまくいけば、誰かが最終的にこれを得る方法を見つけるでしょう。 – xaralis

答えて

6

サービスという共通の問題であると思われますそれはapache、gunicorn + supervisor、daemontoolsなどのdjangoサービスを実行していますが、常に正しい環境変数を使用するとは限りません。この場合、gunicornは

を監督者が開始したので、あなたは明示的に環境オプションを使用してUTF-8を使用するように上司に指示する必要がありさ:

environment=LANG=en_US.UTF-8, LC_ALL=en_US.UTF-8, LC_LANG=en_US.UTF-8 
+2

Supervisor 3.0a8(Debian Squeezeで提供されているバージョン)のように見えますが、 'environment'オプションは設定ファイルの' [supervisord] 'セクションでグローバルに指定する必要があります。 '[program:*]'セクションでは認識されません。 – akaihola

+0

akaiholaありがとう、私はそれを探して最後の3時間を過ごした..... – migajek

+0

ありがとう、これは素晴らしい仕事。 – Marco

1

私はUnicodeEncodeErrorをを与えgenericpath.pyと同じ問題を持っていました非ASCII文字でファイル名をアップロードしようとしたとき。

私は、Python 2.7でnginx、uwsgi、およびdjangoを使用していました。

  1. は、/ etcは/ nginxの/ nginxのに追加:

    すべてがサーバー上でローカルにではなく、[OK]を働いた

    は、ここで私が撮った手順は次のとおりです。confに(問題を解決しませんでした)

    http { 
        charset utf-8; 
    } 
    
  2. 私は見出しの下にリストされ、ここでの指示に従っなど/デフォルト/ロケール(問題を解決しませんでした)

    LANGUAGE="en_US.UTF-8" 
    
  3. に次の行を追加'成功' https://code.djangoproject.com/wiki/ExpectedTestFailures(問題を解決しませんでした)このチケットを越え見つかり

    aptitude install language-pack-en-base 
    
  4. https://code.djangoproject.com/ticket/17816 ロケール情報私にとって

Djangoのビュー

import locale 

def locales(request): 
    """Display the locales""" 
    locales = "Current locale: %s %s -- Default locale: %s %s" % (
     locale.getlocale() + locale.getdefaultlocale()) 
    default_encoding = sys.getdefaultencoding() 
    file_system_encoding = sys.getfilesystemencoding() 

    context = { 
     'locales': locales, 
     'default_encoding': default_encoding, 
     'file_system_encoding': file_system_encoding, # affects file uploads 
    } 
    return render(request, 'testing/locales.html', context) 

Djangoのテンプレート

<h2>Locales</h2> 
<p>{{ locales }}</p> 

<h2>Default Encoding</h2> 
<p>{{ default_encoding }}</p> 

<h2>File System Encoding</h2> 
<p>{{ file_system_encoding }}</p> 

で起こっていたことに、サーバー上のビューをテスト示唆しており、問題は、ということでした私はロケールがなく、私のUbuntuサーバーにデフォルトのロケールがありませんでしたが(私のローカルOSX開発マシン上にそれらを持っていましたが)、ASCII以外のファイルPythonでUnicodeEncodeErrorを発生させても、名前/パスは正しくアップロードされませんが、実動サーバー上でのみアップロードされます。

ソリューション

私は例えば、私のサイトと私のサイト管理者uwsgi設定ファイル の両方にこれを追加の/ etc/uwsgi-皇帝/家臣/私のサイト-CONFIG-iniファイル

env = LANG=en_US.utf8 

更新

は、ドッキングウィンドウする以上移動した後、私は再び同じエラーを取得し始めました。 さらに調べてみると、uwsgi djangoのインスタンスimport sys; sys.getfilesystemencoding()または{{ file_system_encoding }}がANSI_X3.4-1968を返していたことに気付きました。しかし、私自身のpythonインスタンスを起動してimport sys; sys.getfilesystemencoding()を実行した場合、UTF-8が得られます。 ANSI_X3.4-1968形式はUnicodeEncodeErrorを投げているものです。

は、したがって、上記のこの回答に記載されているuwsgiソリューションに加えて、私はまた、dockerfile

ENV LANG en_US.UTF-8 
RUN apt-get update && install -y locales && \ 
    sed -i -e "s/# $LANG.*/$LANG UTF-8/" /etc/locale.gen && \ 
    locale-gen --purge &&\ 
    update-locale LANG=$LANG 

それとも、あなただけのシェルでこれを実行できるドッキングウィンドウを使用していない場合は、私のジャンゴにこれを追加する必要がありました

$ export LANG=en_US.UTF-8 

次に、上記のRUNコマンドを実行します(ただし、RUNは実行しないでください)。

参考文献:あなたは、このための修正を

http://stackoverflow.com/a/37246853/3003438 
https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/uwsgi/ 
+0

これは、ステップバイステップの診断ガイドが付いた素晴らしい答えです。なぜ私はそれほど大きな議決権がないのか分かりません。 Ubuntuの場合、あなたの言語の言語パックが必要であることに注意してください。だから、 'LANG' envをスペイン語とすると、' aptitude install language-pack-es-base'になります。他のすべての言語と同様です。 –

関連する問題