🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

2560閲覧

Linux環境のDjangoで日本語を含むファイル名の扱いについて

mackerel6.023

総合スコア317

CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/11/21 05:46

編集2019/11/21 06:38

環境情報

  • OS:CentOS 7.7(64bit)
  • Python:3.6.8 (yumでインストール)
  • Django:2.2.7
  • mod_wsgi:4.6.8

発生した現象

csvファイルを保存する処理を実行するコードをメイン関数でCUIから実行した場合は、日本語を含むファイル名でも保存できるが、同じ処理をDjangoから呼び出した場合、ファイルのopen関数でasciiで扱えないコードが入っているというエラーが発生する。
Print文ではエラーにならず、今のところOpen関数だけで確認している現象。
Windows環境ではDjangoでもエラーにならない。

コード

python

1 def saveCsv(self, key_word) : 2 filename=os.path.join(self.output_path, 'csv') 3 with open(filename, 'w', encoding='SJIS') as fp: 4 fp.write('検索キーワード:{}\n'.format(key_word)) 5 for word_1 in self.getList(key_word): 6 fp.write('・{}\n'.format(word_1)) 7 for word_2 in self.getList(key_word + word_1): 8 fp.write(',{}\n'.format(word_2)) 9

エラーが発生するのはopen関数。※write関数ではない。
ファイル名に日本語が含まれているときだけエラーになる。(asciiしか使えなくなってる)
ファイルの先頭に「# -- coding: utf-8 --」をつけても変化しない。
setting.pyのDEFAULT_CHARSETを指定しても変化しない。(そもそもデフォルトはUTF8)

考察

理由は不明だが、Linux環境でDjangoを使うとどこかでシステム的なアクセスにasciiのみしか使えなくなる制限がかかる様子。
ただ、CUIで呼び出しても再現しないので、mod_wsgiの問題かもしれない。
ファイルの書き込みはSJISを指定して書き込んでおり、それについては日本語が含まれていても問題なく書き込めるので、文字コードが扱えないわけではない。

知りたいこと

回避方法があれば教えてほしいです。

エラーメッセージ(追記)

Internal Server Error: /create_csvfile, referer: http://testhost/result Traceback (most recent call last):, referer: http://testhost/result File "/python/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner, referer: http://testhost/result response = get_response(request), referer: http://testhost/result File "/python/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response, referer: http://testhost/result response = self.process_exception_by_middleware(e, request), referer: http://testhost/result File "/python/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response, referer: http://testhost/result response = wrapped_callback(request, *callback_args, **callback_kwargs), referer: http://testhost/result File "/python/venv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view, referer: http://testhost/result return view_func(*args, **kwargs), referer: http://testhost/result File "/my_app/main/views.py", line 29, in create_csvfile, referer: http://testhost/result google_maping_obj.saveCsv(keyword), referer: http://testhost/result File "/my_app/scraping/get_csvfile.py", line 56, in saveCsv, referer: http://testhost/result with open(filename, 'w', encoding='SJIS') as fp:, referer: http://testhost/result UnicodeEncodeError: 'ascii' codec can't encode characters in position 69-76: ordinal not in range(128), referer: http://testhost/result , referer: http://testhost/result

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mackerel6.023

2019/11/21 06:10

含まれていないですね。 asciiのみしか使えなくなってることが問題のようですので。 作ったcsvをダウンロードしてExcelで開く要件があるので、中身はSJISで作っています。 ・・・今回の質問には直接関係はありませんが。
dodox86

2019/11/21 06:29

> open関数でasciiで扱えないコードが入っているというエラー 具体的に、どのような文字列でどこに出力されていますか。また、CUIで動作させるときとmod_wsgiで動作させるときのPythonインタープリターは、まったく同一のものでしょうか。
dodox86

2019/11/21 06:43 編集

[回答のコメント欄に移動したため、削除しました]
guest

回答1

0

ベストアンサー

※再現できる環境がない為、推測での回答となります。

Linuxのファイルシステム上のファイル名は単なるバイナリ列で、ターミナル上でファイル名を表示する際は、ターミナルの文字コードに合わせて表示されているに過ぎません。今どきのLinuxディストリビューションは環境変数LANGja_JP.UTF-8にセットされていることがほとんどだと思いますが、バイナリ列でファイル名が保存されるときにもUTF-8前提でファイルシステムに保存されているはずです。Djangoの稼動時にそのDjangoサーバーが動いている環境で環境変数LANGに値がセットされていないと、UTF-8の日本語ファイル名が正しく処理できないのかもしれません。openの実行の前に環境変数LANGをセットすると状況が変わるかもしれませんので、試してみてください。尚、CUIで実行したときにはOKだということですので、その環境でecho $LANGと実行し、LANG環境変数の値をあらかじめ確認してください。

Python3

1# 無理やりセットしてみる。 2os.environ["LANG"]="ja_JP.UTF-8" 3 4with open(filename, 'w', encoding='SJIS') as fp: 5...色々

投稿2019/11/21 06:13

dodox86

総合スコア9256

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mackerel6.023

2019/11/21 06:21

ご回答ありがとうございます。 すみません、書き漏れていましたが、それは試しました。 ですが、変化なしでした。
dodox86

2019/11/21 06:26

そうですか。回答を早まったようです。ちなみに発生するエラーとは、具体的にどのようなものなのでしょう。質問文中に追記してください。
dodox86

2019/11/21 06:43

こちらはQiitaでの記事ですが、関係していませんでしょうか。UnicodeEncodeError: 'ascii' codec ...あたりのエラー文字列は同じようです。 [mod_wsgiで動かす時に、UnicodeDecodeErrorが出てしまう]https://qiita.com/kanjirz50/items/81104b60049ad7140b30
mackerel6.023

2019/11/21 06:51

ありがとうございます。 正解でした。とても勉強になりました。 ちなみにCentOSでは「/etc/sysconfig/httpd」に書かれていますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問