如何在烧瓶中使用 QuerySelectField?

Posted

技术标签:

【中文标题】如何在烧瓶中使用 QuerySelectField?【英文标题】:how to use QuerySelectField in flask? 【发布时间】:2013-07-27 02:05:55 【问题描述】:

我正在尝试在烧瓶表单中填充 sqlalchemy 请求的结果的选择字段。

代码如下:

def possible_book():
    return Book.query.with_entities(Book.id).all()

class AuthorForm(Form):
    familyname  = TextField('familyname', [validators.Required()])
    firstname   = TextField('firstname', [validators.Required()])
    book_list = QuerySelectField('book_list',query_factory=possible_book,get_label='title',allow_blank=True)

这是模板:

 <form action="" method="post" name="edit_author" enctype="multipart/form-data">
     form.hidden_tag()
    <p>Veuillez donner son prénom (obligatoire) :    form.firstname(value=author.firstname)</p>
    <p>Nom de famille (obligatoire) : form.familyname(value=author.familyname)</p>
    <p>Livre : form.book_list</p>

    <p><input type="submit" value="Envoyer"></p>
 </form>

查看:

@app.route('/edit_author/<number>', methods = ['GET', 'POST'])
   def edit_author(number):
   if number == 'new':
      author = []
   else:
      author = Author.query.filter_by(id = number).first()
   form = AuthorForm()
   if form.validate_on_submit():
      a = Author(firstname= form.firstname.data, familyname= form.familyname.data)
      a.books = form.book_list.data

       db.session.add(a)
       db.session.commit()
   return redirect('/admin')
return render_template('edit_author.html', form = form, author = author)

模型(只贴了关联表和作者表,大部分列都不行)

author_book = db.Table('author_book',
    db.Column('author', db.Integer, db.ForeignKey('author.id')),
    db.Column('book', db.Integer, db.ForeignKey('book.id'))
)

class Author(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    firstname = db.Column(db.String(64), index = True)
    familyname = db.Column(db.String(120), index = True)
    website = db.Column(db.String(120))
    dateofbirth = db.Column(db.DateTime)
    placeofbirth = db.Column(db.String(120))
    nationality = db.Column(db.String(120))
    biography = db.Column(db.Text)
    photo = db.Column(db.String(120))
    books = db.relationship('Book', secondary=author_book,backref=db.backref('author', lazy='dynamic'))

我目前收到此错误:

UnmappedInstanceError: Class 'sqlalchemy.util._collections.KeyedTuple' is not mapped

我真正想要的是选择字段显示作者姓名和他的号码,并将作者号码返回给应用程序(返回到头部称为“add_author”的函数)。

谢谢。

【问题讨论】:

您是否测试过您的 possible_book() 方法并确保它按预期工作? 我不知道你所说的“经过测试”是什么意思。 possible_book 只是一个查询,它可以工作,没问题。它只是返回整个书籍列表(或作者,如果您使用另一面)。但我很确定它需要更多的东西来通过表单或模板或其他东西来解释。这就是我想知道的!这是我不明白的:如何使它与表单一起工作? 【参考方案1】:

一个可能的问题是wtforms.ext.sqlalchemy.fields.QuerySelectField 需要一个 SQLAlchemy 查询对象,而不是具体化列表。只需从您的 possible_book 返回中删除 all() 调用,即可将未实现的查询返回给 WTForms:

def possible_book():
    return Book.query.with_entities(Book.id)

【讨论】:

我试过了,好像没有解决问题。我仍然有同样的错误。我认为我应该将每个查询结果放在一个元组中(调试器谈论映射元组......)但我不知道如何正确使用它!【参考方案2】:

你有两个问题:

    正如 Sean Vieira 在他的回答中指出的那样,query_factory 回调应该返回一个查询,而不是结果。

    query_factory 回调应该返回完整的实体,在您的案例书籍中,而不是书籍 ID。我相信QuerySelectField 必须尝试使用​​查询结果,就好像它们是映射对象一样,但 ids(作为 KeyedTuple 实例返回)不是。

我认为这是编写回调函数的正确方法:

def possible_book():
    return Book.query

【讨论】:

仅仅使用Book.query,似乎找到了答案的开始!现在,我有了选择字段! 亲爱的@Miguel 你能帮我解决这个sqlalchemy.exc.InterfaceError in Flask 的问题吗?我使用 QuerySelectField 并引发错误。我不知道如何解决它。谢谢

以上是关于如何在烧瓶中使用 QuerySelectField?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Flask WTForms 和 WTForms-SQLAlchemy QuerySelectField 会产生太多无法解包的值?

如何在烧瓶登录中使用多个用户类?

如何在烧瓶中使用多个Mongodb

如何在 apache windows 10 中使用烧瓶修复错误 500

如何使用烧瓶创建动态文件发送算法

如何在烧瓶中使用从 ajax 发布的数据?