I created a simple CRUD app using Flask and FlaskForm. I have a table where the last name, first name, birthdate, and sex are displayed coming from the database. Beside each name are links labeled as delete and update. When you click on update, you are routed to the update page with a form where the form fields corresponding to the last name, first name, birthdate, and sex should be populated. Sex is a select field with options Male and Female, how do I populate this based from the database? Using FlaskForm, I tried {{form.sex(value=user_to_update.sex)}}
but it does not populate.
Here is my Update route:
@app.route('/update/<int:id>', methods=['GET', 'POST'])
def update(id):
form = Form()
user_to_update = TblPatient.query.get_or_404(id)
if request.method == 'POST':
user_to_update.lastname = form.lastname.data
user_to_update.firstname = form.firstname.data
user_to_update.birthdate = form.birthdate.data
user_to_update.sex = form.sex.data
db.session.commit()
return redirect(url_for('add_record'))
return render_template('update.html', form=form, user_to_update=user_to_update)
Here is the FlaskForm part:
class Form(FlaskForm):
lastname = StringField('Last Name', validators=[DataRequired()])
firstname = StringField('Firstname', validators=[DataRequired()])
birthdate = DateField('Date of Birth', format='%Y-%m-%d', validators=[DataRequired()])
sex = SelectField('Sex',
choices=['Select', 'Male', 'Female'],
default='Select',
validators=[DataRequired()])
submit = SubmitField('submit')
Here is my update.html where the form fields except for sex are populated:
<form action="{{request.path}}" method="post">
{{form.hidden_tag()}}
<fieldset>
<legend>Patient Info</legend>
<p>
{{form.lastname.label}} <br/>
{{form.lastname(value=user_to_update.lastname, size=30)}}
</p>
<p>
{{form.firstname.label}} <br/>
{{form.firstname(value=user_to_update.firstname, size=30)}}
</p>
<p>
{{form.birthdate.label}} <br/>
{{form.birthdate(value=user_to_update.birthdate)}}
</p>
<p>
{{form.sex.label}} <br/>
{{form.sex(value=user_to_update.sex)}}
</p>
</fieldset>
<br/>
{{form.submit}}
</form>
This is the home page:
When I click on update, it redirects me to the update page in question. How do I populate the sex field based on FlaskForm?
CodePudding user response:
If the names of the database columns match those of the form's input fields, you can simply pass the database object to the form and the fields will be automatically populated. You do not need to pass the data to the input fields within the template.
patient = Patient.query.get_or_404(patient_id)
form = PatientForm(request.form, obj=patient)
An alternative to using the obj
attribute is the assignment using the data
attribute. See the documentation for the Form
class.
In addition, you can then use the populate_obj
function to transfer the form data to the database object.
form.populate_obj(patient)
The following example shows you how your endpoint should look like.
The patient is read from the database and assigned to the form. If the request is of type POST and the entries have been validated successfully, the patient data will be updated using the form.
@app.route('/update/<int:patient_id>', methods=['GET', 'POST'])
def update(patient_id):
patient = Patient.query.get_or_404(patient_id)
form = PatientForm(request.form, obj=patient)
if form.validate_on_submit():
form.populate_obj(patient)
db.session.commit()
return redirect(url_for('add_record'))
return render_template('update.html', **locals())