Python Forum

Full Version: How to hide a FlaskForm IntegerField while retaining its value.
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
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:

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)