动态WTForms SelectField在db

时间:2019-11-03 19:47:36

标签: flask dynamic sqlalchemy flask-sqlalchemy flask-wtforms

我正在尝试通过烧瓶sql-alchemy将数据从SQL表'School'中提取到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)

但是,它只以某种方式显示“ School.name”,以及如何以表格形式显示。 另外,它应该显示的条目数是正确的(3,因为数据库中有3个学校条目)

1 个答案:

答案 0 :(得分:0)

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

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

在上述理解中,在每个循环school(小写的s)中,都是类School(大写的“ S”)的实例。

在sqlalchemy中,类(不是类的实例)上列属性的字符串表示形式返回列的数据库标识,例如:"<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.id, School.name)实例创建一个school元组。请注意,“ School”为大写字母“ S”,这意味着您最终在呈现模板时为数据库中的每个学校呈现列的数据库标识的字符串表示形式。答案很简单,只需将您的理解更改为:

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

...但是,一般而言,在使用sqlalchemy和python时,了解差异非常重要。