2013-07-26 11 views
7

Ich versuche, ein Auswahlfeld mit den Ergebnissen einer Sqlalchemy-Anfrage in einer Kolbenform gefüllt zu haben.Wie verwende ich QuerySelectField in der Flasche?

sind hier der Code:

<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> 

Ansicht:

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) 

Dies ist die Vorlage ist

@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) 

Das Modell (klebte nur die assoziative Tabelle und der Autor Tisch, Viel von der Spalte sind nicht in Frage)

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')) 

ich diesen Fehler zur Zeit erhalten:

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

Was wirklich ist, ich will, dass das Auswahlfeld den Namen des Autors und seine Nummer zeigen, und gibt den Autor Nummer der App (auf die Funktion „add_author " auf dem Kopf).

Vielen Dank.

+0

Haben Sie getestet Ihre possible_book() -Methode und sicherzustellen, dass sie wie vorgesehen funktioniert? – codegeek

+0

Ich weiß nicht, was Sie mit "getestet" meinen. Das possible_book ist nur eine Abfrage, und es funktioniert, kein Problem. Es juste zurück die ganze Liste der Bücher (oder Autoren, wenn Sie die andere Seite verwenden). Aber ich bin ziemlich sicher, dass es etwas mehr benötigt, um von der Form oder der Vorlage oder etwas anderem interpretiert zu werden. Das frage ich mich! Das ist, was ich nicht verstehe: Wie man es mit der Form arbeiten lässt? – 22decembre

Antwort

6

Sie haben zwei Probleme:

  1. Als Sean Vieira wies darauf hin, in seiner Antwort, der query_factory Rückruf sollte zurückkehren eine Abfrage, nicht die Ergebnisse.

  2. Der Rückruf query_factory sollte vollständige Entitäten zurückgeben, in Ihrem Fall Bücher, nicht Buch-IDs. Ich glaube, die QuerySelectField muss versuchen, die Ergebnisse der Abfrage zu verwenden, als ob sie zugeordnete Objekte sind, aber die IDs (zurückgegeben als KeyedTuple-Instanzen) sind nicht.

Ich denke, dies ist der richtige Weg ist, um die Callback-Funktion zu kodieren:

def possible_book(): 
    return Book.query 
+0

nur mit Book.query, es scheint den Anfang der Antwort gefunden zu haben! Jetzt habe ich das selectfield! – 22decembre

+0

Sehr geehrte @Miguel können Sie mir bitte helfen mit diesem [sqlalchemy.exc.InterfaceError in Flask] (http: // stackoverflow.com/Fragen/24732871/sqlalchemy-exc-interfaceerror-in-Kolben) Frage. Ich habe ** QuerySelectField ** verwendet und es kommt zu einem Fehler. Ich weiß nicht, wie ich es beheben kann. Vielen Dank – Max

3

Ein mögliches Problem ist, dass wtforms.ext.sqlalchemy.fields.QuerySelectField ein SQLAlchemy-Abfrageobjekt erwartet, keine materialisierte Liste. Entfernen Sie einfach den all() Anruf von Ihrer possible_book Rückkehr eine unmaterialized Abfrage WTForms zurückzukehren:

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

Ich habe es versucht, und es scheint das Problem nicht zu lösen. Ich habe immer noch den gleichen Fehler. Ich denke, ich sollte jedes Abfrageergebnis in ein Tupel setzen (der Debbugger spricht über ein zugeordnetes Tupel ...), aber ich weiß nicht, wie man es nachher nicht richtig benutzt! – 22decembre

Verwandte Themen