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

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

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

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Django

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

Python

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

Q&A

解決済

1回答

2626閲覧

pandasで場所を指定してcsv保存する方法or csvファイルを起動する方法

ktg_st

総合スコア33

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Django

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

Python

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

0グッド

0クリップ

投稿2020/06/17 17:03

編集2020/06/19 16:05

djangoを使ってcsvファイルをダウンロード出来るようには出来たのですが、場所のして方法が分かりません。
自分のみが使うのであれば別のディレクトリに保存する方法は分かるのですが、webアプリとしてブラウザから開いた場合にcsvを保存する場所を指定する方法はないでしょうか?

やりたいこと
・固定でデスクトップに保存する
・保存先指定のダイアログが出る
なんてことが出来ればと思っています。

それかダウンロードではなく、csvを起動する方法があればそこからユーザーが勝手に保存先を決められるのですが、何か良い方法はないでしょうか。

ちなみに出力はpandasのto_csvで行っています。

df.to_csv('a.cv')

調べたところあまりdjangoでpandasで出力している記事がなく(英語は分かりません)情報が少なく行き詰ってます。
よろしくお願いします。

追記

response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=a.csv' df.to_csv(path_or_buf=response,sep=';',float_format='%.2f',index=False,decimal=",")

上記試しましたが上手くいきませんでした。

mixins.pyでcsv出力をしています。(views.pyだと上手く行かなかった)
だから上手く行かないのでしょうか?

mixins.py class CsvMixin(Week_CsvMixin): def get_week_schedules(self, start, end, days): shop = get_object_or_404(Shops, pk=self.kwargs['shops_pk']) user= User.objects.filter(shops__shop=shop) b =[] for a in user: b.append(a) lookup = { '{}__range'.format(self.date_field): (start, end), } queryset = self.model.objects.filter(**lookup) days = {day: [] for day in days} df = pd.DataFrame(days) a=1 for schedule in queryset: if schedule.user in b: if a == 1: user=schedule.user.last_name+' '+schedule.user.first_name date= schedule.date start_time=schedule.get_start_time_display() end_time = schedule.get_end_time_display() time = start_time+'-'+end_time ddf =pd.DataFrame({date:time},index =[user]) df = pd.concat([df,ddf],axis=0) df.fillna(" ", inplace=True) a = 2 if user != schedule.user.last_name+' '+schedule.user.first_name: user=schedule.user.last_name+' '+schedule.user.first_name date= schedule.date start_time=schedule.get_start_time_display() end_time = schedule.get_end_time_display() time = start_time+'-'+end_time ddf =pd.DataFrame({date:time},index =[user]) df = pd.concat([df,ddf],axis=0) df.fillna(" ", inplace=True) else: user=schedule.user.last_name+' '+schedule.user.first_name date= schedule.date start_time=schedule.get_start_time_display() end_time = schedule.get_end_time_display() time = start_time+'-'+end_time ddf =pd.DataFrame({date:time},index =[user]) df[date]= df[date].astype(str) df.at[user,date] =time df.fillna(" ", inplace=True) # csv保存------------------- df.fillna(" ", inplace=True) today = datetime.datetime.today() day = today.strftime("%Y%m%d") # df.to_csv(day + '_list.csv',encoding= "utf_8_sig")←動作はするが、manage.pyと同じ場所に保存される      ↓エラーは出ないが出力はされない response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=a.csv' df.to_csv(path_or_buf=response,sep=';',float_format='%.2f',index=False,decimal=",") return df def get_week_calendar(self): calendar_context = super().get_week_calendar() calendar_context['df'] = self.get_week_schedules( calendar_context['week_first'], calendar_context['week_last'], calendar_context['week_days'] ) return calendar_context
views.py class Shift_csv(mixins.CsvMixin, generic.TemplateView): model = Schedule template_name = 'shift/shift_csv.html' date_field = 'date' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) shop = get_object_or_404(Shops, pk=self.kwargs['shops_pk']) context['shops']= User.objects.filter(shops__shop=shop) context['shopnum']=self.kwargs['shops_pk'] calendar_context = self.get_week_calendar() context.update(calendar_context) return context

views.pyの書き方的に多分変なんだと思いますが、強引にやりました。
viewsでcsv出力のcodeを書くと上手く行きませんでした。

df =context['df'] df.to_csv('a.csv')

みたいに書きましたが上手く動作せず、結果mixinsで書く感じになってます。
出力されるならどこに書いてもいいんですが、、。

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

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

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

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

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

guest

回答1

0

ベストアンサー

HttpResponseオブジェクトを作成すれば実現できます。

python

1from django.http import HttpResponse 2... 3response = HttpResponse(content_type='text/csv') 4response['Content-Disposition'] = 'attachment; filename=hogehoge.csv'

投稿2020/06/17 17:57

編集2020/06/18 21:38
yymmt

総合スコア1615

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

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

ktg_st

2020/06/18 16:14

上手くいかず、、。 追記しました、確認いただければと思います。
yymmt

2020/06/18 17:59 編集

該当するコードはview.pyの中に書きます。この状況から真面目にやると大改造になりそうな予感がします。簡単そうなのは - Shift_csvクラスのgetメソッドを上書きする(get_context_dataを使わない) - urlpatternsに別のエントリを作成してそこに飛ばす という感じだと思います。後者の場合ならviews.pyを以下のようにすれば良いです。 from django.http import HttpResponse CSV_DATA = """ 1,2,3,a,b,c 4,5,6,d,e,f """ def index(request): response = HttpResponse(content_type="text/csv") response["Content-Disposition"] = "attachment; filename=hogehoge.csv" response.write(CSV_DATA[1:]) return response
ktg_st

2020/06/19 16:37

def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) shop = get_object_or_404(Shops, pk=self.kwargs['shops_pk']) context['shops']= User.objects.filter(shops__shop=shop) context['shopnum']=self.kwargs['shops_pk'] calendar_context = self.get_week_calendar() context.update(calendar_context) の上記部分でmixinsにpk送ってdfを作成させているのですが、それをどうやってviewに呼び出せばいいのか分からずminxin内でcsvを試みました。 クラスじゃないと継承が出来ない?と思うので、その辺がよくわかりません。 objects.filterを使っているのでそこにpk送らないといけないんですよね。 viewsのshift_csv内のdef追加して、get_context_dataからdfを引っ張ってきてって感じなるのでしょうか? とりあえずdfをどうやって持ってくるかが良くわからないんですよね。 mixinsに少し追記しました。 ちなみにcsv出力ボタンはdfをhtmlに表示しているページに置いてあり、その表示されている表をcsvしたいのです。
yymmt

2020/06/19 21:22 編集

「画面に表示する」「CSVをダウンロードする」という2つの動作を1つのviewで実現しようとしているのが原因です。 - 画面表示の実装: model(データ) -> 画面表示用view -> 画面表示(Template) - CSVダウンロードの実装: model(データ) -> CSVダウンロード用view -> CSVダウンロード と2つに分けるのが良いと思います。2つ目のviewに対するURLは、画面表示テンプレートからURL等が貼られていて、ボタンが押されるとこのviewとリンクしたURLが呼びされるイメージです。
yymmt

2020/06/19 21:26

すいません、もう一点。画面に表示されているテーブルをCSVに出力するのであれば、その部分はJavaScriptで組むのもありです。
ktg_st

2020/06/20 15:27

表示とcsv出力のviewsは分けて作成してあります(内容は殆ど同じで飛ばしているページが違うだけ)継承しているmixinsが違うものになっており、csv出力の方がto_csvの記載が追加されているだけです。 質問に記載されているcodeはすべてcsv出力のみ行っているつもりです。 pkを使ってデータ検索に使っており、pkを使ってデータを呼び出す際にget_context_dataがなければいけないのかと思っています。 getメソッドをいまいち理解しきれていない部分があり、どう書けばいいのか分かりません。 def get()などで書くと、pk関連でエラーが出ます。 def csv(self,**kwargs)と書くと引数の数が違うとエラーが出ます。 def csv()とするとpkを受け取ったことでエラーになります。 python自体も初心者でして、JavaScriptは完全に無知なので少し勉強してい見ます。
ktg_st

2020/06/20 15:41

class Shift_csv(mixins.CsvMixin, generic.TemplateView): model = Schedule template_name = 'shift/shift_csv.html' date_field = 'date' def get(self, request, **kwargs): context = self.get_context_data(**kwargs) shop = get_object_or_404(Shops, pk=self.kwargs['shops_pk']) calendar_context = self.get_week_calendar() context.update(calendar_context) df = context['df'] response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=hogehoge.csv' response.write(df) return response 上記codeで行けました!! ただ文字化けします! context = self.get_context_data(**kwargs)の部分なのですが、getメソッドはdef get_context_dataと作らなくても、getメソッドが持っているものなのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問