如何在Flask下拉选择框中填充模型数据?——Flask新手求助TreatmentForm下拉框不显示患者列表问题
解决Flask中Treatment Form下拉框无法显示患者列表的问题
嘿,我来帮你搞定这个问题!你的下拉框没加载出患者列表,主要是表单设置、模型拼写还有数据库查询时机这几个地方出了问题,我给你一步步拆解修正:
核心问题分析
- 表单choices格式错误:你直接把
Patient.query.all()塞进SelectField的choices里,但SelectField需要的是(值, 显示文本)的元组列表,而且不能在类定义时执行数据库查询(这时应用上下文还没初始化,查询会失效)。 - 模型字段拼写错误:Patient模型里名字字段写成了
ame,但路由创建患者时用的是name=form.name.data,这会导致数据库存不了姓名,连__repr__里的self.name都会报错! - 其他小bug:性别选择框的choices格式不对,
Treatement模型拼写多了个e(应该是Treatment)。
修改后的完整代码
1. 修正Forms.py
from flask_wtf import FlaskForm from wtforms import StringField, SelectField, FloatField, TextAreaField, SubmitField from wtforms.validators import DataRequired from models import Patient class PatientForm(FlaskForm): name = StringField('Name', validators=[DataRequired()]) age = StringField('Age', validators=[DataRequired()]) # 修正性别选项格式:(值, 显示文本) gender = SelectField('Gender', validators=[DataRequired()], choices=[('Male', 'Male'), ('Female', 'Female')]) identity_number = StringField('IC / Passport / Matric Number', validators=[DataRequired()]) contact_number = StringField('Contact Number', validators=[DataRequired()]) submit = SubmitField('Submit') class TreatmentForm(FlaskForm): # 先不预设choices,在视图里动态加载 patient = SelectField('Patient', validators=[DataRequired()]) medication = SelectField('Medication', choices=[("1", "One")], validators=[DataRequired()]) test = StringField('Test', validators=[DataRequired()]) cost = FloatField('Cost', validators=[DataRequired()]) initials = TextAreaField('Initials', validators=[DataRequired()]) submit = SubmitField('Submit')
2. 修正Models.py
from datetime import date from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class Patient(db.Model): id = db.Column(db.Integer, primary_key=True) # 修正字段名:ame → name name = db.Column(db.String(100), nullable=False) age = db.Column(db.String(), nullable=False) gender = db.Column(db.String(), nullable=False) identity_number = db.Column(db.String(), nullable=False) patient_created_at = db.Column(db.Date, default = date.today()) contact_number = db.Column(db.String(), nullable=False) doctor_id = db.Column(db.Integer, db.ForeignKey('doctor.id'), nullable=False) def __repr__(self): return f"Patient('{self.id}', '{self.name}')" # 修正模型名拼写:Treatement → Treatment class Treatment(db.Model): id = db.Column(db.Integer, primary_key=True) # 建议存patient_id而非字符串,方便关联查询 patient_id = db.Column(db.Integer, db.ForeignKey('patient.id'), nullable=False) treatment_created_at = db.Column(db.Date, default=date.today()) medication = db.Column(db.String, nullable=False) test = db.Column(db.String, nullable=False) cost = db.Column(db.Float, nullable=False) initials = db.Column(db.Text, nullable=False) doctor_id = db.Column(db.Integer, db.ForeignKey('doctor.id'), nullable=False) # 关联Patient模型,方便后续查询 patient = db.relationship('Patient', backref='treatments')
3. 修正Routes.py(添加Treatment路由并动态加载患者列表)
from flask import render_template, redirect, url_for, flash from flask_login import login_required, current_user from app import app, db from forms import TreatmentForm, PatientForm from models import Patient # 你的new_patient路由保持不变 @app.route("/patient/new", methods=['GET', 'POST']) @login_required def new_patient(): form = PatientForm() if form.validate_on_submit(): patient = Patient(name=form.name.data, age=form.age.data, gender=form.gender.data, identity_number=form.identity_number.data,contact_number=form.contact_number.data, doctor=current_user) db.session.add(patient) db.session.commit() flash('Patient has been registered!', 'success') return redirect(url_for('patients')) return render_template('create_patient.html', title='Register New patient', form=form, legend='Register New patient') # 新增创建Treatment的路由,动态设置患者下拉框选项 @app.route("/treatment/new", methods=['GET', 'POST']) @login_required def new_treatment(): form = TreatmentForm() # 动态生成患者选项:(患者ID, 患者姓名) form.patient.choices = [(patient.id, patient.name) for patient in Patient.query.all()] if form.validate_on_submit(): treatment = Treatment( patient_id=form.patient.data, medication=form.medication.data, test=form.test.data, cost=form.cost.data, initials=form.initials.data, doctor_id=current_user.id ) db.session.add(treatment) db.session.commit() flash('Treatment record has been created!', 'success') return redirect(url_for('treatments')) # 假设你有treatments列表页面 return render_template('create_treatment.html', title='New Treatment', form=form, legend='New Treatment')
额外说明
- 动态设置choices是在视图函数里,每次请求都会查询最新的患者列表,新增患者后下拉框会自动更新。
- 把Treatment模型的patient字段改成patient_id并关联Patient模型,后续查询患者的治疗记录会更便捷。
- 记得用Flask-Migrate迁移数据库,因为修改了模型字段。
内容的提问来源于stack exchange,提问作者Shimol Khan
相关产品推荐
相关产品推荐

