Вопрос

I am using python, flask and Jinja to make a simple video playlist maker that runs directly on the Raspberry pi, so a user can author a video playlist via the local network. It simply edits a text file as a playlist, each line literally being the videos to playback that a separate script uses to play videos.

there are 2 forms on one page, here is the template, for simplicity it counts the fields as it increments through the list of video name strings as jinja makes the html page.

   <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>

when the first form 'add' is submitted it adds this text to the text file using the number generated by {{ counter + loop.index0 }} and this works fine.

@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)

but with the other form 'edit' it does not work returning 0 for "fillen" instead of the number, putting {{ items }} works and the file name is sent but the number always returns 0!!! what is the difference between these 2 sections!! looking at the source of the page it is generating the numbers for the "filen" form but goes missing on 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)
Это было полезно?

Решение

You should move the (second) form tag inside the loop.

With your current code, multiple fields with same name are generated inside the same form tag. When this form is submitted, only one of the value (first one i.e. 0) is sent.

<!-- 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>

What you want is different form block for every video.

<!-- 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>

So, to fix your code for the second 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>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top