动态WTForms SelectField显示数据库中表的列标题



我正试图通过flask SQL alchemy将数据从SQL表"学校"拉入SelectField:

形式:

school_choices = [(School.id, School.name) for school in School.query.all()]
school = SelectField('Your school', validators=[DataRequired()], choices=school_choices)

路线:

def register():
if current_user.is_authenticated:
return redirect(url_for('home'))
form = RegistrationForm()
if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
user = User(username=form.username.data, email=form.email.data, password=hashed_password, school=form.school.data)
db.session.add(user)
db.session.commit()
flash('Your account has been created! You are now able to log in', 'success')
return redirect(url_for('login'))
return render_template('register.html', title='Register', form=form)

型号:

class School(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)

然而,不知何故,它只显示"学校名称",只是它在表格中的书写方式。此外,它应该显示的条目数量是正确的(3个,因为数据库中有3个学校条目(

问题在于您对列表的理解,即为select字段构建值,以及在类与类实例上呈现列属性之间的差异:

school_choices = [(School.id, School.name) for school in School.query.all()]

在以上理解中,在每个循环中,school(小写"s"(是类School(大写"s"(的一个实例。

在sqlalchemy中,Class(而不是类的实例(上的列属性的字符串表示返回列的数据库标识,例如:"<tablename>.<columnname>",或者在本例中为"school.name"。这就是构建查询的方式,例如,尝试运行print(School.__table__.select()),它将打印SELECT school.id, school.name FROM School。该查询中的列标识来自对column实例的"字符串化"。

但是,当我们访问类实例(例如school = School(name="myschool")(上的列属性时,我们会获得存储在数据库中的列的值。例如print(school.school) # myschool

根据上面的列表理解,您为数据库中的每个school实例创建了一个(School.id, School.name)元组。请注意"学校"的大写字母"S",这意味着当模板呈现时,您最终会呈现数据库中每个学校的列数据库标识的字符串表示形式。答案很简单,只需将你的理解改为:

school_choices = [(school.id, school.name) for school in School.query.all()]

但是,在使用sqlalchemy和python时,理解它们之间的区别是非常重要的。

最新更新