我有一个简单的Flask Web应用程序,其中显示了我从TSV文件(使用Pandas)读取的表格。对于每一行,我正在显示索引,一些文本,一个标签(正/负),一个日期和一个“更改标签”按钮。
我希望能够在TSV文件中为单击“更改标签”按钮的特定文本更改标签。我当时在考虑使用/edit/<index>
这样的URL,以便可以使用URL中传递的索引在TSV中找到相应的行并进行更改,但是没有运气。
例如,当我单击表第一行中的“更改标签”按钮时,URL为/edit/0
这就是我所拥有的。
@app.route('/admin', methods=['GET', 'POST'])
def admin():
if request.method == 'GET':
return render_template('admin.html')
if request.method == 'POST':
if request.form['submit'] == 'Manage':
from_date = '01-01-1900'
to_date = '01-01-2900'
df = pd.read_csv('dataset.tsv', sep='\t', encoding='utf-8')
indexes = df.index.values.tolist()
texts = df['text'].values.tolist()
labels = df['label'].values.tolist()
dates = df['date'].values.tolist()
data = zip(indexes, texts, labels, dates)
return render_template('admin.html', from_date=from_date, to_date=to_date, data=data)
@app.route('/edit/<id>', methods=['GET', 'POST'])
def edit():
if request.method == 'GET':
return render_template('admin.html')
if request.method == 'POST':
# TODO, open TSV file and change label
return render_template('admin.html')
<!doctype html>
<head>
<link rel="stylesheet" media="screen" href ="static/bootstrap.min.css">
<link rel="stylesheet" href="static/bootstrap-theme.min.css">
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
</head>
<div class="container">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Text</th>
<th scope="col">Label</th>
<th scope="col">Date</th>
<th scope="col">Edit</th>
</tr>
</thead>
<tbody>
{% for index, text, label, date in data %}
<tr>
<th>{{ index }}</th>
<th>{{ text }}</th>
<th>{{ label }}</th>
<th>{{ date }}</th>
<th>
<form action="/edit/{{ index }}" method="post" role="form">
<input type="submit" name="submit" value="Change Label" class="btn btn-info">
</form>
</th>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</html>
我知道问题与<form action="/edit/{{ index }}" method="post" role="form">
中的admin.html
有关,因为它无法传递URL中的索引。当我单击任何按钮时,它会将我重定向到/edit/
,而没有任何索引。可以通过某种方式在URL中传递变量{{ index }}
还是应该以其他方式完成?
答案 0 :(得分:1)
对于这种任务,我建议您使用url_for。
我认为这是首选方法,因为它可以让您构建有意义且始终有效的URL,而不必依赖用户表单。
例如,如果您决定制作一个API或用户决定共享书签以便快速实现Web应用程序中的特定功能,这将对您大有帮助。
这是documentation中的一个相关示例(如果您想了解更多内容,请查看URL Building):
from flask import Flask, url_for
app = Flask(__name__)
@app.route('/')
def index():
return 'index'
@app.route('/login')
def login():
return 'login'
@app.route('/user/<username>')
def profile(username):
return '{}\'s profile'.format(username)
with app.test_request_context():
print(url_for('index'))
print(url_for('login'))
print(url_for('login', next='/'))
print(url_for('profile', username='John Doe'))
这也是如何从small app I wrote编写模板的示例(它具有基本的CRUD功能,因此您可能会发现它很有用):
<div data-role="content">
<h3 class="center">Edit restaurant</h3>
<label for="textinput-hide" class="ui-hidden-accessible">Text Input:</label>
<form id="new-restaurant-form" action="{{url_for('edit_restaurant', restaurant_id=restaurant.id)}}" method="POST" target="_parent">
<input type="text" name="restaurant-name" id="textinput-hide" placeholder="{{restaurant.name}}" value="">
<fieldset class="ui-grid-a">
<div class="ui-block-a"><a href="#" data-role="button" data-rel="back" data-theme="c">Cancel</a></div>
<div class="ui-block-b"><button type="submit" data-role="button" data-transition="flow" data-theme="b"
id="btn-add-new-ok">Ok</button></div>
</fieldset>
</form>
</div>
答案 1 :(得分:1)
您为什么不利用隐藏的表单输入?在您的表单中,添加隐藏的输入元素:
{% for index, text, label, date in data %}
<tr>
<th>{{ index }}</th>
<th>{{ text }}</th>
<th>{{ label }}</th>
<th>{{ date }}</th>
<th>
<form action="/edit" method="post" role="form">
<input type="hidden" id="index" name="index" value="{{ index }}">
<input type="submit" name="submit" value="Change Label" class="btn btn-info">
</form>
</th>
</tr>
{% endfor %}
然后在您的路线上
@app.route('/edit', methods=['GET', 'POST'])
def edit():
if request.method == 'GET':
return render_template('admin.html')
if request.method == 'POST':
index = int(request.form['index'])
# Now use `index` to change your TSV
return render_template('admin.html')