You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flask下拉选择框中填充模型数据?——Flask新手求助TreatmentForm下拉框不显示患者列表问题

解决Flask中Treatment Form下拉框无法显示患者列表的问题

嘿,我来帮你搞定这个问题!你的下拉框没加载出患者列表,主要是表单设置、模型拼写还有数据库查询时机这几个地方出了问题,我给你一步步拆解修正:

核心问题分析

  1. 表单choices格式错误:你直接把Patient.query.all()塞进SelectField的choices里,但SelectField需要的是(值, 显示文本)的元组列表,而且不能在类定义时执行数据库查询(这时应用上下文还没初始化,查询会失效)。
  2. 模型字段拼写错误:Patient模型里名字字段写成了ame,但路由创建患者时用的是name=form.name.data,这会导致数据库存不了姓名,连__repr__里的self.name都会报错!
  3. 其他小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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:59:06