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

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

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

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

Python

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

Q&A

解決済

1回答

2138閲覧

[Django] csvファイルをURLから読み込み

taisei_02

総合スコア4

Django

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

Python

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

0グッド

0クリップ

投稿2020/10/20 03:42

編集2020/10/20 03:46

djangoで機械学習でデータ分析ができるwebアプリを作っています。

csvファイルをアップロードし、学習済みのモデルでデータ分析をしたいのですが、csvファイルの読み込みにアップロード先のurl(今回は、/media/csvファイル名)を指定してcsvファイルからデータフレームを読み込む所でつまずいています。

色々とコードを下に書きましたが、
views.pyのupload_dfにpd.read_csvでデータを入れる所でエラーが発生してしまいます。

プロジェクト名は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 uploaded_url %} <p>ファイルのアップロード場所は、<a href="{{ uploaded_url }}">{{ uploaded_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')), ] # only in development 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 import pandas as pd import pickle # Create your views here. from django.http import HttpResponse from django.core.files.storage import FileSystemStorage training_data_df = pd.read_csv("training_data.csv") with open("trained_model.pickle", mode="rb") as f: model = pickle.load(f) def index(request): if request.method == "GET": return render(request, 'index.html') elif request.method == "POST" and 'file' not in request.FILES: return render(request, 'index.html') else: file = request.FILES['file'] fileobject = FileSystemStorage() filedata = fileobject.save(file.name, file) upload_url = fileobject.url(filedata) #ここでエラーが発生 下のどちらで試してもエラーが起きます。 # upload_df = pd.read_csv("../media/" + filedata) # upload_df = pd.read_csv(upload_url) return render(request, 'index.html', {"uploaded_url": upload_url})

どなたかお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

回答

python

1upload_url = fileobject.url(filedata)

でURL形式での文字列が得ることが出来るのと同様に、
fileobject.path(filename)でフルパスを得ることが出来ます。

※利用例

python

1def index(request): 2 if request.method == "GET": 3 return render(request, 'index.html') 4 elif request.method == "POST" and 'file' not in request.FILES: 5 return render(request, 'index.html') 6 else: 7 file = request.FILES['file'] 8 fileobject = FileSystemStorage() 9 filedata = fileobject.save(file.name, file) 10 upload_url = fileobject.url(filedata) 11 12 upload_df = pd.read_csv(fileobject.path(filedata)) 13 14 # upload_dfで何かするとか 15 ... 16 17 18 # テンプレートに渡すとか 19 return render(request, 'index.html', { 20 "uploaded_url": upload_url, 21 "uploaded_df": upload_df, 22 })

質問のコードでは何故ダメか(コメントへの補足)

「(現時点で)存在する変数は何を扱っているか」「どこでプログラムを実行しているか」を意識する必要があります。

前提:view関数の、主要な変数について

※以下は、自分が前回含め回答を書いてた際に認識しているものです

  • fileobject: FileSystemStorageのインスタンス。ファイルの管理が役割
  • filedata: fileobject.save()で保存した際のファイル名(ファイル名のみ)
  • upload_url: fileobjectによって組み立てられた、アップロード済みファイルのURL(HTML用)

upload_url ではダメな理由

upload_urlはあくまでURL用のため、ローカルでのファイルアクセス用に使うのは不適切です。

"../media/" + filedata ではダメな理由

アプローチとして「ローカルファイルへのアクセス」という観点では間違っていないのですが、
相対パスはプログラム実行時のカレントディレクトリから解決されていくため、
「カレントディレクトリ」がどこかを把握できていないと、正しく組み立てられることが出来ません。

偶然噛み合うことがありますが、正しい情報を元にパスを組み立てる必要があります。
(おそらくですが、"./media/"+filedataだと正しく機能してしまっている可能性があります)

※今回のケースでは、アップロード以降のローカルでの処理をfileobjectに委ねているので、
「実際のファイルパス」もfileobjectに委ねるのが理想です。
(実際にpath()というオブジェクトを持っています)

投稿2020/10/20 14:36

編集2020/10/20 15:28
attakei

総合スコア2740

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

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

taisei_02

2020/10/20 14:51

度々ありがとうございます!! うまくいきました。 ですが、私が書きましたやり方のようには、なぜ出来ないのでしょうか? filedataやupload_urlなどはURLのデータではないのでしょうか。
attakei

2020/10/20 15:29

回答を編集して書いてみました。 要約すると「正しいアプローチで絶対パスでアクセスするのが近道」といった感じになります。
taisei_02

2020/10/21 03:14

詳しく解説していただきありがとうございます!! ローカルのurlとhtml用のurlを混在して考えてしまっていたようですね。 "./media/"+filedata"でもうまくいくこと確認できました!ですが、絶対パスを用いるほうが間違いがないということですね! 本当に助かりました。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問