質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Django

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

Python

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

Q&A

解決済

1回答

1303閲覧

Djangoでファイルをアップロード

taisei_02

総合スコア4

Django

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

Python

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

0グッド

0クリップ

投稿2020/10/19 14:08

djangoでwebアプリを作っているのですが、ファイルのアップロードでつまずきました。
csvファイルを選択し、アップロードを押すと、アップロード先のurlが分かるように表示させたいのですが、
index.htmlの{% if upload_url %} が反応せず、元のindex.htmlが表示されます。
/media/にファイルはアップロードできているようです。
また、何もファイルを選択せずにアップロードを押してもエラー画面になります。

プロジェクト名はjob_offer,アプリケーション名はjob_offer_appとしています。
下に色々とプログラムを載せてみました。

job_offer/settings.py

(略) INSTALLED_APPS = [ (略) 'job_offer_app.apps.JobOfferAppConfig', ] MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

job_offer_app/templates/index.html

{% load static %} <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>トップページ</title> </head> <body> <h1>csvファイルをアップロードしてください。</h1> <form action="{% url 'home' %}" method="POST" class="post-form" enctype="multipart/form-data"> {% csrf_token %} <input type="file" accept =".csv" name="file"> <button type="submit" class="save btn btn-default">アップロード</button> </form> {% if upload_url %} <p>ファイルのアップロード場所は、<a href="{{ upload_url }}">{{ upload_url }}</a>です。</p> {% endif %} </body> </html>

job_offer/urls.py

from django.contrib import admin from django.conf import settings from django.conf.urls.static import static from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('job_offer_app.urls')), ] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

job_offer_app/urls.py

from django.conf import settings from django.conf.urls.static import static from django.urls import path from . import views urlpatterns = [ path('', views.index, name="home"), ] # only in development if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

job_offer_app/views.py

from django.shortcuts import render from django.http import HttpResponse from django.core.files.storage import FileSystemStorage def index(request): if request.method == "GET": return render(request, 'index.html') else: file = request.FILES['file'] fileobject = FileSystemStorage() filedata = fileobject.save(file.name, file) upload_url = fileobject.url(filedata) return render(request, 'index.html')

urlsの最後の二行が必要だという記事を見たので、追加してみましたが解決しません。
お願いします。

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

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

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

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

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

attakei

2020/10/19 15:05

プロジェクト自体のurls.pyには何が記載されていますか?
taisei_02

2020/10/19 15:21

上から3つ目のプログラム、job_offer/urls.py がプロジェクト自体のurls.pyです。 これのことでしょうか。
attakei

2020/10/19 15:51

あ、確かにそうですね。失礼しました。 だとすると、settings.DEBUGがどうなっているかが気になりますね。 動作確認をしている環境下がDEBUG=Trueでないと、このif分岐には入らないのですが、 現状job_offer/settings.pyの略した部分でDEBUGはどうなっているでしょうか。
taisei_02

2020/10/19 15:52

確認したところ、Trueになっていました。。
guest

回答1

0

ベストアンサー

view関数内で定義された変数(今回はupload_url)をテンプレートに引き渡すには、
render()呼び出し時に適切に引き渡す必要があります。

job_offer_app/views.py

diff

1from django.shortcuts import render 2from django.http import HttpResponse 3from django.core.files.storage import FileSystemStorage 4 5def index(request): 6 if request.method == "GET": 7 return render(request, 'index.html') 8 else: 9 file = request.FILES['file'] 10 fileobject = FileSystemStorage() 11 filedata = fileobject.save(file.name, file) 12 upload_url = fileobject.url(filedata) 13- return render(request, 'index.html') 14+ return render(request, 'index.html', {"upload_url": upload_url})

テンプレート側にあるupload_urlはview側から引き渡されて、初めて機能します。

投稿2020/10/19 16:05

attakei

総合スコア2738

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

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

taisei_02

2020/10/19 16:19

ありがとうございます。無事、アップロード先のurlを表示できました!! 定義した変数をちゃんと引き渡す必要があるのですね! この表示はできたのですが、何もファイルを選択せずにアップロードを押すとエラーのページになってしまう原因もわかりますでしょうか?余力がありましたら、教えていただきたいです。。
attakei

2020/10/19 16:28

多分ですけど、Djangoのエラー表示として ==== MultiValueDictKeyError at / 'file' ==== と出ていませんか? これは、何もファイルを選択せずにフォーム送信を行うと、 アプリの側では何も受け取ってないのにも関わらず、 view関数がrequest.FILES['files']が存在することを前提に処理しようとしているからです。 view関数の処理時にrequestの中身を適切に判定することで、 「何もファイルを選択せずにアップロードを押されたら〇〇する」という処理を書けるので、 そうすれば適切な表示に出来ると思います。
taisei_02

2020/10/20 02:17

なるほど、viewsのなかで何も選ばれなかった場合の処理もちゃんと書く必要があるのですね。 POSTでの処理をもう少し詳しくかいてみようと思います。 ご丁寧にありがとうございました!!非常に助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問