使用Flask和Jinja2时特定标签的表单数据未通过
我正在使用Python、Flask和Jinja来制作一个简单的视频播放列表生成器,这个程序可以直接在树莓派上运行,用户可以通过本地网络创建视频播放列表。它实际上就是编辑一个文本文件,文件中的每一行都是要播放的视频,这些视频会被另一个脚本用来播放。
在同一页面上有两个表单,这里是模板。为了简单起见,它在生成HTML页面时,会逐个数视频名称字符串的字段。
<body>
<h2> Add videos to Playlist </h2>
<form action="add" method="POST" >
<select name="video">
{% set counter = 0 -%}
{% for videos in videos %}
<option value="{{ counter + loop.index0 }}">{{ videos }}</option>
{% endfor %}
</select>
<input type="submit" value="Add">
</form>
<h2> Playback List </h2>
<form action="edit" method="POST" >
{% set counter = 0 -%}
{% for items in playlist %}
{{ items }}
<input type="hidden" name="filen" value="{{ counter + loop.index0 }}">
<input type="submit" name="editype" value="up">
<input type="submit" name="editype" value="down">
<input type="submit" name="editype" value="delete">
<br>
{% endfor %}
<input type="submit" name="editype" value="Next Video">
<input type="submit" name="editype" value="Reset">
</form>
</body>
当第一个表单“添加”被提交时,它会使用{{ counter + loop.index0 }}生成的数字把文本添加到文本文件中,这个过程运行得很好。
@app.route('/add', methods = ['POST'])
def add():
vidtoadd = request.form['video']
vidurl = glob.glob('/home/pi/videos/*.mp4')
videos = [v.replace('/home/pi/videos/','') for v in vidurl]
f = open('playlist.txt','a')
f.write('%s \n' % videos[int(vidtoadd)])
f.close()
playlist = [item.strip() for item in open('playlist.txt', 'r')]
templateData = {
'videos' : videos, 'playlist' : playlist
}
return render_template('main.html', **templateData)
但是对于另一个表单“编辑”,它却不工作,返回的“fillen”总是0,而不是应该的数字。把{{ items }}放进去是可以的,文件名也能发送,但数字总是返回0!这两个部分之间有什么区别呢?查看页面源代码时,发现“filen”表单的数字是生成出来的,但在POST时却消失了?
@app.route('/edit', methods = ['POST'])
def edit():
edit = request.form['editype']
videotoedit = request.form['filen']
print '%s %s received!' % (edit,videotoedit)
if edit == 'Next Video':
os.system('killall omxplayer.bin')
vidurl = glob.glob('/home/pi/videos/*.mp4')
videos = [v.replace('/home/pi/videos/','') for v in vidurl]
playlist = [item.strip() for item in open('playlist.txt', 'r')]
templateData = {
'videos' : videos, 'playlist' : playlist
}
return render_template('main.html', **templateData)
1 个回答
0
你应该把第二个表单标签放到循环里面。
现在的代码会在同一个表单标签里生成多个同名的字段。当你提交这个表单时,只会发送其中一个值(第一个,也就是 0
)。
<!-- Following is currently generated by your template. -->
<form action="edit" method="POST">
<input type="hidden" name="filen" value="0">
...other fields here...
<input type="hidden" name="filen" value="1">
...and so on...
</form>
你想要的是每个视频都有不同的表单块。
<!-- Following is what it should be. -->
<form action="edit" method="POST">
<input type="hidden" name="filen" value="0">
...other fields here...
</form>
<form action="edit" method="POST">
<input type="hidden" name="filen" value="1">
...other fields here...
</form>
所以,要修复你的代码中的第二个表单-
<h2> Playback List </h2>
{% set counter = 0 -%}
{% for items in playlist %}
<form action="edit" method="POST" >
{{ items }}
<input type="hidden" name="filen" value="{{ counter + loop.index0 }}">
<input type="submit" name="editype" value="up">
<input type="submit" name="editype" value="down">
<input type="submit" name="editype" value="delete">
</form>
<br>
{% endfor %}
<form action="edit" method="POST" >
<input type="submit" name="editype" value="Next Video">
<input type="submit" name="editype" value="Reset">
</form>