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

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

詳細はこちら
Django

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

981閲覧

[Django/Pythonanywhere] マルチバイト言語(仏語)を使ったファイルが読み込めない

luciano

総合スコア11

Django

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/01/05 02:09

前提・実現したいこと

ランダムに画像を読み込み表示させる試作中のDjangoアプリで、マルチバイトの文字を含むファイル名の画像を読み込めるようにしたいと試行錯誤しています。
ローカルの仮想環境下では問題なかったのですが、Pythonanywhere上にデプロイするとこの問題が発生します。

発生している問題・エラーメッセージ

具体的には、フランス語の"é"を含むファイルです。例えば"présent.png"というファイルがランダムに選ばれた場合、以下のエラーが出ます。

GET http://ユーザー名.pythonanywhere.com/static/myapp/images/pre%CC%81sent.png 404 (Not Found)

一方、同じような性質と思われる"ç"を含むファイル("ça.png")は、「%C3%A7a.png」という形で問題なく読み込まれ表示されます。

試したこと

「Django 多言語化/国際化」等で調べてみて、setting.pyに以下を追加してみたのですが、解決出来ませんでした。
また、「LANGUAGE_CODE = 'fr'」にしてもダメでした。

Python

1from django.utils.translation import ugettext_lazy as _ 2 3MIDDLEWARE = [ 4 'django.middleware.security.SecurityMiddleware', 5 'django.contrib.sessions.middleware.SessionMiddleware', 6 'django.middleware.locale.LocaleMiddleware', #←これを追加 7 'django.middleware.common.CommonMiddleware', 8 'django.middleware.csrf.CsrfViewMiddleware', 9 'django.contrib.auth.middleware.AuthenticationMiddleware', 10 'django.contrib.messages.middleware.MessageMiddleware', 11 'django.middleware.clickjacking.XFrameOptionsMiddleware', 12] 13 14LANGUAGE_CODE = 'en-us' 15 16LANGUAGES = [ 17 ('fr', _('French')), 18 ]

補足情報(FW/ツールのバージョンなど)

ネット上では、翻訳させるなどの本格的な対応への情報はあるのですが、このような初歩的な問題に対する答えやヒントが見つからなかったので、ここで質問させて頂くことにしました。

どうかよろしくお願い致します。

[環境]
Mac Os Catalina
Django 3.1.1
Python 3.8

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

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

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

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

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

hoshi-takanori

2021/01/05 04:15

開発中は static ファイルは django が処理してるでしょうけど、pythonanywhere にデプロイすると static ファイルは一か所に集められるようなので、たぶん http アクセスの際には django は関与してないのでは。(解決策は分かりませんが、もしかしたら django で処理するようにしたら変わるのかも? でも、無駄な処理が発生しますけどね…。) https://help.pythonanywhere.com/pages/DjangoStaticFiles
luciano

2021/01/05 04:23

コメントありがとうございます。 Pythonanywhere上でのstaticファイルは仰る通り一ヶ所に集められており、普通のアルファベットのみの名前のファイルは問題なく読み込まれて表示されています。
hoshi-takanori

2021/01/05 05:40

私が言いたかったのは、一般的な web サービスは http リクエストをいったん web サーバー (pythonanywhere は nginx を使ってるようです) で受けて、アプリへのアクセスなら django に中継するけど、static ファイルは web サーバーが直接処理している可能性が高く、その場合 django というか python コードをいじってもどうにもならないのではないか、ということです。 その場合、 ・static ファイルをコピーする処理 (collectstatic) の際にファイル名がおかしくなってないか ・pythonanywhere の web サーバーの設定でファイル名の扱いがどうなってるか をチェックする必要がありますが、ユーザーが確認できるかは不明です。 また、static ファイルを web サーバーに任せずに django で処理する方法もあるので、それを検討するのもありかと。(うまくいくとは限りませんが…。)
luciano

2021/01/05 07:14

コメントの趣旨は理解致しました。 丁寧にご説明頂きありがとうございます。 ご指摘頂いた点をチェックしてみます。
luciano

2021/01/15 08:20

フィードバックが遅くなってしまって申し訳ありません。 新参者ゆえ、この場所での作法がよく分かっておらず、コメント頂いたいずれの方の欄にコメントバックすべきかがわかりませんでした。 そこで「回答」頂いた方の方にその後の状況をコメントさせて頂きました。失礼でしたら、お詫び申し上げます。
guest

回答2

0

「pre%CC%81sent」はアキュート付きeを1文字のU+00E9「é」でなく普通の「e」に結合文字のU+0301「 ́ 」を付けた2文字で表した表記です。
Macのファイル名は日本語の濁音半濁音にも結合文字を使うことで有名ですし、きっと結合文字で扱われているのでしょう。
一方のçは合成済み文字で扱われるのでしょうかね。ちょっと不統一が不思議ですが。
まあ何にせよ、どこかでファイル名が変わっているのが原因でしょうから、見た目に惑わされず中身のバイト列の違いを調べて合成済み文字か結合文字列かどちらかに統一するとよいでしょう。

参考: Unicodeの特殊な文字 “結合文字列”

投稿2021/01/05 12:59

ikadzuchi

総合スコア3047

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

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

luciano

2021/01/05 23:38

ご回答ありがとうございます。 なるほど、まさに盲点ですね。 この線で探ってみます。
luciano

2021/01/15 08:20

フィードバックが遅くなってしまって申し訳ありません。 ご指摘頂いた方向で探って見たのですが、如何せん基礎知識が乏しいものでうまく解決出来ませんでした。 そこでやむなく、ファイル名をアクサンを外した"e"に変えて試してみたのですが、それでも同じくファイルが表示されませんでした。 Safariの「ページソースを見る」でチェックしてみると「[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (present.png, line 0)」のエラーが表示されており アラート部分を「ネットワーク」で見ると、ファイル名は"present.png"なのですが、何故か"タイプ"の欄には"html"と表示されます。 上記エラーのリンクを開いてみると、Page not found (404) Request Method:GET、Request URL:http://ユーザー名.pythonanywhere.com/static/myapp/images/present.png となり、 URLconfでページを探しに行っているように見受けられます。 ちなみに、Pythonanywhereの"Files"で確認してみても、ファイル名は"present.png"です。 collectstaticが悪さをしているのかもと(ファイル名変更後、一旦collectstaticをかけています)、Pythonanywhereの"Files"から直接アップロードしてみても変わりません。 このようにまたスタックしている状況ですが、ここから何かお気づきの点がありますでしょうか? 引き続きご教示頂ければ幸いです。
ikadzuchi

2021/01/16 09:15

なるほど、ファイル名を普通のeに変えてエラーが起こるとなるとちょっと私には分かりませんね。
guest

0

("ça.png")は、「%C3%A7a.png」

2バイトでエンコードしてますが、文字コードは何でしょうか。
UTF8ではないですよね

これをUTF8でURLエンコードしてやってみてはどうでしょうか

投稿2021/01/05 02:13

y_waiwai

総合スコア88038

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

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

luciano

2021/01/05 02:24

早速のご回答ありがとうございます。 settings.pyもviews.pyも冒頭に「# -*- coding: utf-8 -*-」、また、templateでも、<html lang="fr">「<meta charset="utf-8">」を入れてはいるのですが。
y_waiwai

2021/01/05 02:35

ああ、双方の文字ともUNICODEの1バイト文字なんですね。これは失礼しました そしたら、 "pr%E9sent.png" ではどうでしょう。 #うーん、無理っぽいなあ。。
luciano

2021/01/05 04:29

コメントありがとうございます。 力づくで"é"を"e"のファイル名に変えれば何とかなりそうな気もするのですが、後学のためにも、ここはきちんと理解した上で解決したいと思っていますので、引き続きご教示頂ければ幸いです。 ローカルでは問題なかったので、リモート(Pythonanywhereだけではなく)上での対応に、何か足りないことがあるのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問