CircAnalyzer
CircAnalyzer

Reputation: 704

Python Flask Sqlite3 Web App Delete from database table row

I have a very simple application that creates, removes, and updates records in a sqlite3 database using Python and Flask. I am currently working on the remove function and have hit a road block. Below is my code for my view that shows the records in the table:

<!doctype html>
<html>
   <body>

      <table border = 1>
         <thead>
            <td>Name</td>
            <td>Address>/td<
            <td>city</td>
            <td>Pincode</td>
         </thead>

         {% for row in rows %}
            <tr>
               <td>{{row["name"]}}</td>
               <td>{{row["addr"]}}</td>
               <td> {{ row["city"]}}</td>
               <td>{{row['pin']}}</td>
           <td><form action = "/foo" method = "POST">
           <button id ="w3-btn">delete</button>
        </form> </td>
            </tr>
         {% endfor %}
      </table>

      <a href = "/">Go back to home page</a>

   </body>
</html>

As can be seen from the code, I have a delete button for each record displayed. How can I make it such that if the user clicks on the delete button on any given row, that row will be deleted from the table? I would like to know how I can specify the selected row, and how I can send that information/data to 'foo' in my app.py, and how the function in app.py would take that data as an input argument.

Upvotes: 1

Views: 3638

Answers (2)

furas
furas

Reputation: 142631

If you have row["pin"]

then you can use hidden field in form with method="POST"

<form action="/foo" method="POST">
    <input type="hidden" value="{{ row["pin"] }}"/>
    <button id="w3-btn">delete</button>
</form>

or using method="GET" and ?id=some_id in url

<form action="/foo?id={{ row["pin"] }}" method="GET">
    <button id="w3-btn">delete</button>
</form>

Or even as normal link (which you can style as button using CSS)

<a href="/foo?id={{ row["pin"] }}">delete</a>

In view you will have

 # POST

 @app.route('/foo', methods=['POST']) 
 def foo():
      pin = requests.form.get('id')
      print(pin)

 # GET or normal link

 @app.route('/foo') 
 def foo():
      pin = requests.args.get('id')
      print(pin)

Read doc: http://flask.pocoo.org/docs/0.11/


If you use url without ?id= but "/foo/some_id"

action="/foo/{{ row["pin"] }}"

<a href="/foo/{{ row["pin"] }}">delete</a>

or using url_for()

action="{{ url_for('foo', pin=row["pin"]) }}"

<a href="{{ url_for('foo', pin=row["pin"]) }}">TEST</a>

then you will need

 @app.route('/foo/<pin>') 
 def foo(pin):
      print(pin)

Upvotes: 3

davidism
davidism

Reputation: 127180

Create a delete view that takes an id to delete.

@app.route('/<int:id>/delete', methods=['POST'])
def delete(id):
    r = Record.query.get_or_404(id)
    db.session.delete(r)
    db.session.commit()
    return redirect(url_for('index'))

The delete form's action is the generated url to the delete view.

<form method=post action="{{ url_for('delete', id=r.id) }}">

This assumes that each row has an id attribute. For example:

from flask import Flask, redirect, url_for, render_template_string
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
db = SQLAlchemy(app)

class Item(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)

db.create_all()
db.session.add_all((
    Item(name='abc'),
    Item(name='def'),
    Item(name='ghi'),
))
db.session.commit()

@app.route('/')
def index():
    items = Item.query.all()
    return render_template_string('''<ul>{% for item in items %}
        <li>{{ item.name }} -
        <form method=post action="{{ url_for('delete', id=item.id) }}">
            <button type=submit>delete</button>
        </form></li>
    {% endfor %}</ul>''', items=items)

@app.route('/<int:id>/delete')
def delete(id):
    item = Item.query.get_or_404(id)
    db.session.delete(id)
    db.session.commit()
    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(debug=True)

Upvotes: 1

Related Questions