I got the dynamic selectfield finally working which shows the subcategories for that one category you choose. The only problem now is that whenever I want to store the entry and submit, it just reloads the page and resets the subcategories and won't let me store the new entry.
This is the tutorial I followed:
app.py
from flask import Flask, render_template, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from wtforms import SelectField
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
app.config['SECRET_KEY'] = 'secret'
db = SQLAlchemy(app)
class City(db.Model):
id = db.Column(db.Integer, primary_key=True)
state = db.Column(db.String(2))
name = db.Column(db.String(50))
class Form(FlaskForm):
state = SelectField('state', choices=[('CA', 'California'), ('NV', 'Nevada')])
city = SelectField('city', choices=[])
@app.route('/', methods=['GET', 'POST'])
def index():
form = Form()
form.city.choices = [(city.id, city.name) for city in City.query.filter_by(state='CA').all()]
if request.method == 'POST':
city = City.query.filter_by(id=form.city.data).first()
return '<h1>State: {}, City: {}</h1>'.format(form.state.data, city.name)
return render_template('index.html', form=form)
@app.route('/city/<state>')
def city(state):
cities = City.query.filter_by(state=state).all()
cityArray = []
for city in cities:
cityObj = {}
cityObj['id'] = city.id
cityObj['name'] = city.name
cityArray.append(cityObj)
return jsonify({'cities' : cityArray})
if __name__ == '__main__':
app.run(debug=True)
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form method="POST">
{{ form.csrf_token }}
{{ form.state }}
{{ form.city }}
<input type="submit">
</form>
<script>
var state_select = document.getElementById("state");
var city_select = document.getElementById("city");
state_select.onchange = function() {
state = state_select.value;
fetch('/city/' + state).then(function(response) {
response.json().then(function(data) {
var optionHTML = '';
for (var city of data.cities) {
optionHTML += '<option value="' + city.id + '">' + city.name + '</option>';
}
city_select.innerHTML = optionHTML;
})
});
}
</script>
</body>
</html>
This is how my code looks:
@app.route("/data/create", methods=["GET", "POST"])
def create():
form = NewEntry()
if form.validate_on_submit():
form.Unterkategorie.choices = [
(Unterkategorie.Name, Unterkategorie.Name)
for Unterkategorie in Unterkg.query.filter_by(
Kategorie="01_GENERAL_REQUIREMENTS"
).all()
]
employee = WissenModel(
Kategorie=form.Kategorie.data,
Unterkategorie=form.Unterkategorie.data,
)
db.session.add(employee)
db.session.commit()
flash(f"Eintrag hinzugefügt!", "success")
return redirect(url_for("RetrieveList"))
return render_template("createpage.html", form=form, title="New Entry")
@app.route("/Unterkategorie/<Kategorie>")
def Unterkategorie(Kategorie):
Unterkategorien = Unterkg.query.filter_by(Kategorie=Kategorie).all()
UnterkategorieArray = []
for Unterkategorie in Unterkategorien:
UnterkategorieObj = {}
UnterkategorieObj["id"] = Unterkategorie.id
UnterkategorieObj["Name"] = Unterkategorie.Name
UnterkategorieArray.append(UnterkategorieObj)
return jsonify({"Unterkategorien": UnterkategorieArray})
My code is lacking this part:
if request.method == 'POST':
city = City.query.filter_by(id=form.city.data).first()
But when I have if form.validate_on_submit():
I shouldn't need the if request.method == 'POST':
right?
Try with form.is_submitted(), then save form.name. Maybe this can help.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.