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)