Mar-03-2020, 10:56 PM
Hi. I have a very small, simple CRUD Web-app that works in every respect but one. Using Flask\SQLAlchemy to connect to a SQLite database. The problem manifests itself in my route: '/edit_tune' when I try to hide the form input named 'id'. The id field is the primary key, auto-generated.
The following code performs flawlessly for both the '/add_tune' and '/edit_tune' routes, instantiating the form which executes appropriately for both GET and POST:
Then, on submitting the form, the value of the id derived from the request object is lost.
In the '/edit_tune' route: id = request.form.get('id') returns None - and the expected error occurs.
I've tried using the HiddenInput widget, with no luck.
How do I hide the IntegerField and yet retain its value on POST?
Here is the code for tune_mgr.py:
The following code performs flawlessly for both the '/add_tune' and '/edit_tune' routes, instantiating the form which executes appropriately for both GET and POST:
class TuneForm(FlaskForm):
id = IntegerField('id')
name = StringField('name', [validators.DataRequired()])
key_sig = StringField('key_sig')But if instead I try on line 2 to suppress the display of the field: id = HiddenField('id') Then, on submitting the form, the value of the id derived from the request object is lost.
In the '/edit_tune' route: id = request.form.get('id') returns None - and the expected error occurs.
I've tried using the HiddenInput widget, with no luck.
How do I hide the IntegerField and yet retain its value on POST?
Here is the code for tune_mgr.py:
import os
from flask import Flask
from flask import render_template
from flask import request
from flask_sqlalchemy import SQLAlchemy
from flask import redirect, url_for
from flask_wtf import FlaskForm
from wtforms import StringField, IntegerField, HiddenField, PasswordField, validators, widgets
from flask import flash
app = Flask(__name__)
# database setup and config
project_dir = os.path.dirname(os.path.abspath(__file__))
database_file = "sqlite:///{}".format(os.path.join(project_dir, "tune_database.db"))
app.config["SQLALCHEMY_DATABASE_URI"] = database_file
db = SQLAlchemy(app)
app.config["SECRET_KEY"] = "Thisisasecret"
# orm model Tune
class Tune(db.Model):
__tablename__ = 'tune'
id = db.Column(db.Integer, unique=True, primary_key=True)
name = db.Column(db.String(80), unique=True, nullable=False)
key_sig = db.Column(db.String(10), unique=False, nullable=True)
def __init__(self, name, key_sig):
self.name = name
self.key_sig = key_sig
def __repr__(self):
return "<Name: {}>".format(self.name)
class TuneForm(FlaskForm):
id = IntegerField('id')
name = StringField('name', [validators.DataRequired()])
key_sig = StringField('key_sig')
#routes
@app.route("/")
def home():
return render_template("home.html")
@app.route("/list")
def list_tunes():
tunes = Tune.query.all()
return render_template("list_tunes.html ", tunes=tunes)
@app.route("/add", methods=["GET", "POST"])
def add_tune():
if request.form:
tune = Tune(name=request.form.get("name"), key_sig=request.form.get("key_sig"))
db.session.add(tune)
db.session.commit()
tunes = Tune.query.all()
return render_template("add_tune.html", tunes=tunes)
else:
tunes = Tune.query.all()
return render_template("add_tune.html", tunes=tunes)
@app.route("/edit", methods=["GET", "POST"])
def edit_tune():
if request.form:
newname = request.form.get("name")
newkey_sig = request.form.get("key_sig")
id = request.form.get('id', widget=widgets.HiddenInput())
tune = db.session.query(Tune).get(id)
form = TuneForm(obj=tune)
tune.name = newname
tune.key_sig = newkey_sig
db.session.commit()
return redirect(url_for('list_tunes'))
else:
idx = request.args.get('index')
tune = Tune.query.get(idx)
form = TuneForm(obj=tune)
return render_template("edit_tune.html", form=form )
@app.route("/delete")
def delete_tune():
idx = request.args.get('index')
return render_template("delete_tune.html", index=idx)
if __name__ == "__main__":
app.run(debug=True)
