Reputation: 704
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
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
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