2013-07-26 79 views
7

我試圖讓一個選擇域填充燒瓶形式的sqlalchemy請求的結果。如何在燒瓶中使用QuerySelectField?

這裏是代碼:

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功能「 在頭上)。

謝謝。

+0

您是否測試possible_book()方法,並確保它按預期工作? – codegeek

+0

我不知道你的意思是「測試」。 possible_book只是一個查詢,它的工作原理沒有問題。它合理地歸還整本書籍(或者如果你使用另一方的作者)。 但我很確定它需要更多的東西來解釋表單或模板或其他東西。這是我想知道的! 這是我不明白:如何使它與表單一起工作? – 22decembre

回答

6

你有兩個問題:

  1. 肖恩·維埃拉在他的回答中指出,該query_factory回調應該返回一個查詢,而不是結果。

  2. query_factory回調應該返回完整的實體,在您的案例書籍,而不是書籍ID。我相信QuerySelectField必須嘗試使用​​查詢的結果,就好像它們是映射對象一樣,但是id(作爲KeyedTuple實例返回)不是。

我認爲這是編寫回調函數的正確方法是:

def possible_book(): 
    return Book.query 
+0

通過使用Book.query,它似乎找到了答案的開始!現在,我有選擇字段! – 22decembre

+0

親愛的@Miguel你能幫我解決這個[sqlalchemy.exc.InterfaceError in Flask](http:// stackoverflow。問題/ 24732871/sqlalchemy-exc-interfaceerror-in-flask)問題。我使用** QuerySelectField **,並引發錯誤。我不知道如何解決它。謝謝 – Max

3

一個可能的問題是wtforms.ext.sqlalchemy.fields.QuerySelectField需要SQLAlchemy查詢對象,而不是物化列表。只需從你的possible_book返回刪除all()調用的unmaterialized查詢返回WTForms:

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

我試過了,似乎沒有解決問題。我仍然有同樣的錯誤。 我想我應該把每個查詢結果放在一個元組(debbugger談論一個映射元組......),但我不知道如何正確使用它後! – 22decembre