How do I get my HTML button to delete the right list item from a SQLite database?

12,406

Solution 1

Just add a hidden input to every form with the element id/name that you want to delete as the value :)

eg.

<form action="{{ url_for('delete_movie') }}" method=post class=delete-movie>
  <input type=hidden value="{{ movie.name }}"name=movie_to_delete />
  <input type=submit />
</form>

Solution 2

IMO, the method in above answer is quite unnecessary. You should pass the movie's name as URL variable:

{% for movie in movies %}
    <li><h1>{{ movie.title }}</h1>
    <form action="{{ url_for('delete_movie', movie_name=movie.name) }}" method=post>
        <input type=submit value=Delete">
    </form>
{% endfor %}

In view function, include the variable in URL rule (i.e. /delete/<movie_name>), then you can get the movie's name as a parameter:

@app.route('/delete/<movie_name>', methods=['POST'])
def delete_movie(movie_name):
    g.db.execute('delete from movies where movie = ?', [movie_name])
    ...

However, in this use case, people normally pass the id value of movie record instead of the name. Here is a minimal example from a similar application:

Template:

<form method="post" action="{{ url_for('delete_movie', movie_id=movie.id) }}">
    <input class="btn" type="submit" name="delete" value="Delete">
</form>

View:

@app.route('/movie/delete/<int:movie_id>', methods=['POST'])
@login_required
def delete_movie(movie_id):
    movie = Movie.query.get_or_404(movie_id)
    db.session.delete(movie)
    db.session.commit()
    flash('Item deleted.')
    return redirect(url_for('index'))
Share:
12,406
Barrett
Author by

Barrett

Shhh. If we're real quiet, maybe they won't realize we don't belong here.

Updated on June 05, 2022

Comments

  • Barrett
    Barrett almost 2 years

    I'm a beginner, so forgive any stupidity in advance. I'm using Flask (and by extension Jinja2) to create a simple web app -- one that basically lets you type a movie into a web form, which adds it to a SQLite database. I've gotten Flask to very nicely iterate through all the movies in the database and print them to the page upon load.

    I want to include a "Delete" button next to each movie. Getting the button to appear is simple. But I'm not sure how to tie the button back to the function delete_movie() such that it will delete the correct movie associated with the button pressed.

    Since there will be a button next to each movie, the form element must be dynamically named, I'm guessing. But if it's dynamically named, how do I pass the correct value back to the function? This is what I've got so far:

    #movies.html
    <div class=page>
        <h1>Movie List</h1>
        <ul class=movies>
        {% for movie in movies %}
            <li><h1>{{ movie.title }}</h1>
            <form action="{{ url_for('delete_movie') }}" method=post class=delete-movie><input type=submit value=Delete name=movie_to_delete"></form>
        {% endfor %}
        </ul>
    </div>
    
    #app.py
    @app.route('/delete', methods=['POST'])
    def delete_movie():
        g.db.execute('delete from movies where movie = ?', [request.form['movie_to_delete']])
        g.db.commit()
        return redirect(url_for('list_movies'))
    

    Thanks in advance for any help!

  • Tommaso Barbugli
    Tommaso Barbugli about 12 years
    @Barrett happy that helped :) please remember to mark the answer as right if it solved your issue :)
  • Barrett
    Barrett about 12 years
    Done. I'm a beginner at Stack Overflow as well as at coding ;)
  • Alessandro De Simone
    Alessandro De Simone over 3 years
    What is the HTML if you want to use the method 'DELETE"? @app.route('/delete/<movie_name>', methods=['DELETE']) the following HTML: `<form action="{{ url_for('delete_movie', movie_name=movie.name) }}" method=delete> ... </form> does not work. Thanks
  • Grey Li
    Grey Li over 3 years
    You can only use GET or POST in HTML. For other methods, you will need to use JavaScript to send the request.