使用烧瓶逐步展示演示
Posted
技术标签:
【中文标题】使用烧瓶逐步展示演示【英文标题】:Showing demo step by step with flask 【发布时间】:2021-07-25 20:06:40 【问题描述】:我想展示一个我在 Python 中使用 Flask 编写的函数的演示。我有一个分配给变量的不同输入和输出的示例列表。 所以我想遍历列表,并在单个页面中单独显示每个示例。提示用户是否想查看如何获得答案的详细说明。并且有两个按钮,我们称它们为“是”和“否”。 如果按下“是”,则会显示一些额外的信息。最后,应该有一个“下一步”按钮,其作用与“否”相同(如下所述) 如果“否”,那么我想继续列表中的下一个示例。
这是怎么做到的?
在我的 *.py 文件中:
@app.route('/demo', methods = ["GET", "POST"])
def demo():
examples = [[first example stuff],[second...], ... ]
for index in range(0, len(examples)):
example = examples[index]
if 'yes' in request.form:
return render_template('demo.html', example=example, answer=True)
elif 'no' in request.form:
pass # Continue with demo
return render_template('demo.html', example=example, answer=False)
在我的 demo.html 模板中:
example
<p>Do you want to see how the answer was reached?</p>
<form method = "post">
<input type = "submit" name = "yes" value = "Sure!">
<input type = "submit" name = "no" value = "No, thanks">
</form>
% if answer %
<!--show extra info -->
(% endif %
这行不通,我只是不知道该怎么做。 我查看了这些链接,但不知道该怎么做:
https://www.codegrepper.com/code-examples/python/how+to+add+next+button+in+flask
How to implement a next button in flask?
谢谢!
【问题讨论】:
使用for
-loop 是完全错误的想法。当您按下按钮时,它会再次运行demo()
,因此它会再次启动for
-loop,它只获得第一个示例。您的按钮应发送当前示例的编号,demo()
应使用此编号获取正确示例的数据
只需在demo()
中使用print()
来显示变量中的值,您会发现这是错误的想法。
也许可以代替<form>
使用普通的<a>
与/demo/1
demo/2
甚至/demo/1/yes
demo/2/no
之类的链接 - 或在<form>
添加带有演示编号的字段
你的 elif ...: pass
没用 - 你可以删除它,代码也能正常工作。
【参考方案1】:
for
-loop 是完全错误的想法。
当您按下按钮时,它会从头开始运行demo
,然后从头开始再次运行for
-loop,因此它总是得到第一个示例。
您应该将示例编号放在form
中作为隐藏字段
<input type="hidden" name="number" value=" example_number "/>
当你按下按钮时从form
获取它
def demo():
number = request.form.get('number', 0) # as default it will use `0`
number = int(number)
button = request.form.get('btn')
首先您可以使用number
和按钮next
、previous
来更改它
if button == 'NEXT':
if number < len(examples)-1:
number += 1
if button == 'PREV':
if number > 0:
number -= 1
稍后您可以使用number
从列表中获取正确的示例
text = examples[number][0]
if button == 'YES':
help = examples[number][1]
else:
help = None
最小的工作示例。
我使用两种形式使其更具可读性。
from flask import Flask, request, render_template_string
examples = [("Hello", "It is first help"), ("World", "It is second help")]
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
number = request.form.get('number', 0) # as default it will use `0`
number = int(number)
button = request.form.get('btn')
print('number before:', number)
if button == 'NEXT':
if number < len(examples)-1:
number += 1
if button == 'PREV':
if number > 0:
number -= 1
text = examples[number][0]
if button == 'YES':
help = examples[number][1]
else:
help = None
print('number after :', number)
print('text:', text)
print('help:', help)
return render_template_string('''
Text: text
% if help %<br>Help: help % endif %
<form method="POST">
<input type="hidden" name="number" value=" example_number "/>
<button type="submit" name="btn" value="YES">YES</button>
<button type="submit" name="btn" value="NO">NO</button>
</form>
<!-- other elements -->
<form method="POST">
<input type="hidden" name="number" value=" example_number "/>
<button type="submit" name="btn" value="PREV">PREV</button>
<button type="submit" name="btn" value="NEXT">NEXT</button>
</form>
''', example_number=number, text=text, help=help)
if __name__ == '__main__':
#app.debug = True
app.run()
【讨论】:
【参考方案2】:您的价值是是和否,谢谢,所以我们可以删除不必要的东西。
<input type = "submit" name = "yes" value = "Sure!">
<input type = "submit" name = "no" value = "No, thanks"
@app.route('/demo', methods = ["GET", "POST"])
def demo():
examples = [[first example stuff],[second...], ... ]
for example in examples:
if request.form.get('yes') is not None:
return render_template('demo.html', example=example, answer=True)
elif request.form.get('no') is not None:
pass
return render_template('demo.html', example=example, answer=False)
【讨论】:
【参考方案3】:这就是我最终的做法。
在我的python文件中:
index :int
# I decided to put the steps as a global list, so that it doesn't assign it to the variable
# each time that demo() and step_by_step() are called, and so that I don't need to pass as argument
demo_steps = [...]
# demo just calls step_by_step(), but it always starts from 0
# So when user clicks on "demo" in navigator link, the demo restarts
@app.route('/demo')
def demo():
global index
index = 0
return redirect(url_for('step_by_step', step=index))
step_by_step(index)
@app.route('/demo/<int:step>', methods = ["GET", "POST"])
def step_by_step(step):
global index, demo_steps
index = min(step, len(demo_steps)-1) # to prevent a user from typing "/demo/20" (for example) in the URL
short_answer = demo_steps[index][0]
detailed_answer = demo_steps[index][1]
if request.method == "POST":
if 'yes' in request.form:
return render_template('demo.html',
short = short_answer,
detailed = detailed_answer,
show_answer = True)
# user clicked 'no' ( = doesn't want detailed explanation),
# or 'next' (after seeing the detailed explanation)
# Either way, we move to the next step in the demo
elif 'no' or 'next' in request.form:
index += 1
if index < len(demo_steps):
return redirect(url_for('step_by_step', step=index))
step_by_step(index)
else:
return redirect(url_for('finished'))
elif request.method == "GET":
return render_template('demo.html',
short = short_answer,
detailed = detailed_answer,
show_answer = False)
@app.route('/finished')
def finished():
return render_template('finished.html') # A simple page saying demo is finished
在我的 demo.html 模板中:
<h1>The short answer is: short </h1>
<p>Do you want to see how the answer was reached?</p>
<form method = "post">
<input type = "submit" name = "yes" value = "Sure!">
<input type = "submit" name = "no" value = "No, thanks">
</form>
% if show_answer %
<h3>These are the steps that the program took to find the answer</h3>
% for step in detailed %
<li> step </li>
% endfor %
<p></p>
<form method = "post">
<input type = "submit" name = "next" value = "Continue">
</form>
% endif %
【讨论】:
以上是关于使用烧瓶逐步展示演示的主要内容,如果未能解决你的问题,请参考以下文章
sql 这些代码片段将演示如何逐步使用PolyBase。你应该有一个blob存储和存储秘密方便