Djangoでfile fieldを使ったアップロードをしたらファイルURLが文字化けする件

▼この記事をSNSでシェアする▼

スポンサーリンク

スポンサーリンク

以前ファイルアップロードの仕方を紹介しました。

しかし、その実装だとある問題が・・・

日本語(マルチバイト文字)がファイル名に含まれていると、ファイルのURLが%まじりになり文字化けしてしまうんです。

ファイルのアップロード処理はうまくいくのですが・・・

個人的に製作しているアプリの実装でmodelFormをつかったファイルアップロードを実装しているのですが、今回はそれを例に説明していきます。

以前の記事がこちらこの内容を踏まえて説明していくので、読んでない方は一度ご覧ください。

事象

画像処理を行うために今回日本語を含むファイル名のパスを取得しようとしてエラーになりました。

admiページから sqlite3にアップロードすると文字化けはせずURL問題なく取得できる感じでした

アップロードフォームはforms.pyでmodelをimportしてHTML上に{{ form.as_p}}と記述しています。

このようなアップロード画面でファイルをあげると、ファイルが正常にアップロードはされ、media配下にファイルが格納されます

models.py

models.pyで定義しているようにアップロードされ、ファイルもmediaディレクトリの指定の箇所に保存されるのですが日本語(マルチバイト)文字を含んでいると

img/%…%12.jpg みたいな形で保存されてしまう。

そのため

views.pyからアップした画像のパスをitem.img.urlで渡そうとしているのですが、どうもこれが文字化けしてしまい、日本語(マルチバイト)を含むファイルのパスが取得できない。

画像変換処理の箇所でexceptionが出て、異常終了してしまいました。

error: (-215:assertion failed) !_src.empty() in function ‘cvtcolor’

色変換処理する際にcv2から指定のパスの画像を読む際に正常に読めず、エラーが表示されたことがデバッグで確認できました。

ちなみに修正前のソースは以下のようになっていました。

修正前のソース

ネットでヒントを探した結果

ネットで原因を探そうとすると、

UnicodeEncodeErrorが出た際の対処法はたくさん出る。

  • LANGUAGE_CODE をjpじゃなくてjaにする
  • /etc/sysconfig/httpd や/etc/apache2/envvars に下記のように設定する

https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/modwsgi/

ただ今回起きたエラーとは別で、アップロードすることがうまくいかない場合はサーバーの文字の設定を疑うといい気がします。

対処法

方針

formから保存する際に保存される画像ファイルのパスをmodels.pyで指定する。

mediaディレクトリ以下の「img/(フォームで入力した画像名).jpg」とします

今回の問題は保存する際にファイル名が文字化けしてしまうことでした。

私の作っているアプリでは画像名(一意制約あり)を画面から入力するので、その名前で画像を保存するようにmodelを書き換えることにします。

やるまえはこれでうまくいくかわかりませんが、結果的にこれがうまくいきました

ソースコード

従来画像のパスを取得してそれを画像ファイルの取得しようしていたが、今回「(フォームで入力した画像名).jpg」で保存するように実装し直しました。

今回変えたポイントをまとめて起きます。

修正後のソースは下記になります。詳細はそこで確認できます。

修正後のソース

models.py

get_image_pathという関数を作り、instance(イメージのデータ)の名前を画像名に設定するように実装しています。

この関数の書き方は以下を参考にしました

参考URL:モデルのFileFIeldについて(Django Document)

views.py

アップロード画面でPOSTメソッドで画像がアップされる処理

10行目でmodels.pyの設定に沿って、ファイルを保存し、11-13行目でDBに保存されたファイルの名前を取得しています。

editImage.py

views.pyの13行目で取得した引数 (item.name)を用いて画像パスを取得する処理

まとめ

本当にこれでいいのか感は否めないです。

調べている限りファイルURLを文字化けさせずに使用する手立てが見当たらなかったので、今回は保存するファイル名を指定するように修正しました

また同時に問題を見つけました。

画像名に記号を入力すると、ファイル名に反映されず下記のエラーが出ます。

エラーは

error: (-215:assertion failed) !_src.empty() in function ‘cvtcolor’で今回紹介した事象と同じものです。

今後バリデーションの実装を入れてそこらへんも解消していこうと思います。

合わせて読みたい

PythonでOpenCVのしきい値処理を応用して、漫画っぽい強調エフェクトもりもりの画像を作る

[/su_bo

スポンサーリンク


関連記事

▼この記事をSNSでシェアする▼

フォローする

メニュー・主な記事カテゴリ

おすすめ特集!




「ゆとり鳥日記」について
ITを中心に関心の赴くままに好きなように書いていく雑記ブログ!管理人が二人います。
◆フクロウ(19卒就活生)
◆トンビ(社会人1年目SE)

詳しいプロフィール
お仕事の依頼・ご要望

ゆとり鳥日記をBTCで応援する