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

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

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

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python

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

Q&A

解決済

1回答

928閲覧

flask stream_with_context

koromooo_

総合スコア8

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Python

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

0グッド

0クリップ

投稿2018/12/15 15:19

編集2018/12/15 15:25

flaskでスクレイピングした画像を表示するWebアプリケーションを製作しています。
スクレイピングに時間がかかるのでダウンロードが終わった画像から順にhtmlに表示をしたいです。
画像はformに利用する予定なのですがそのままrender_templateで返すと画像のダウンロードが終わっていないままformを表示してしまいます。
なので画像をスクレイピングする関数から、終わった画像を返すジェネレータを作り、それに基づいて表示しています。

問題は同じformが1ページに何回も表示されてしまうことです

(例)
--form--
1枚目の画像
--form--
1枚目の画像
2枚目の画像
--form--
1枚目の画像
2枚目の画像
3枚目の画像
.
.
.

(理想)
--form--
1枚目の画像
2枚目の画像
3枚目の画像
.
.
.

関数は
Response(stream_with_context(レンダリングされたhtmlを返すジェネレータ))
を使っています

知りたいのはこのformの部分(変更があった部分だけ)をレンダリングして返す方法です。

html

1{% extends "layout.html" %} 2{% block content %} 3 <form action="{{ url_for('PDFPage')}}" method="post"> 4 5 <!-- CHANGE HERE FROM ... --> 6 7 <table> 8 {% for num,info in hoge %} 9 {% if num <= loaded_img %} 10 <tr> 11 <td> 12 <input type="checkbox" name="more_than_zero" checked> 13 </td> 14 <td><img src="static/{{ f_name }}/{{num}}.jpg" width="10%" height="10%"></td> 15 <td>{{info[0]}}</td> 16 <td>{{info[2]}}</td> 17 <td> 18 <select name="card_num"> 19 <option>{{info[2].rstrip("枚")|int}}枚</option> 20 {% for i in range(info[2].rstrip("枚")|int)[::-1] %} 21 <option>{{i}}枚</option> 22 {% endfor %} 23 </select> 24 </td> 25 </tr> 26 {% endif %} 27 {% endfor %} 28 </table> 29 30 <!-- HERE --> 31 32 <button type="submit">PDFを出力</button> 33 </form> 34{% endblock %}

Python

1 def generate_output(): 2 i = gen.__next__() 3 while True: 4 try: 5 yield render_template('result.html',secret=enumerate(d.secretk),f_name=new_name,loaded_img=i) 6 except: 7 break 8 i = gen.__next__() 9 return Response(stream_with_context(generate_output()))

参考
http://flask.pocoo.org/docs/1.0/patterns/streaming/

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

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

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

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

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

guest

回答1

0

ベストアンサー

テンプレートを使用したストリーミングを行う場合、stream_with_contextに渡すオブジェクトが違うと思われます。
公式サイトを見る限りだと、stream_with_contextに渡すのは、

python

1def stream_template(template_name, **context): 2 app.update_template_context(context) 3 t = app.jinja_env.get_template(template_name) 4 rv = t.stream(context) 5 rv.disable_buffering() 6 return rv

で生成されるようなオブジェクトです。

formが繰り返し生成されてしまうのは、generator(generate_output関数)で毎回、render_templateを呼び出してでテンプレート(result.html)を生成しているからですね。generatorは差分のみ生成を行う関数にする必要があります。

というわけで、差分だけ更新する実装にするためには、上記のstream_templateの関数を追加して、以下のような実装になると思います。

python

1 def generate_output(): 2 i = gen.__next__() 3 while True: 4 try: 5 yield i 6 except: 7 break 8 i = gen.__next__() 9 i = generate_output() 10 return Response(stream_with_context(stream_template('result.html',secret=enumerate(d.secretk),f_name=new_name,loaded_img= i)))

投稿2018/12/22 03:53

yuwki0131

総合スコア160

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問