¿Cómo usar QuerySelectField en el matraz?

Estoy tratando de tener un campo de selección lleno de los resultados de una solicitud sqlalchemy en un formulario matraz.

Aquí está el código:

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) 

Esta es la plantilla:

   {{form.hidden_tag()}} 

Veuillez donner son prénom (obligatoire) : {{form.firstname(value=author.firstname)}}

Nom de famille (obligatoire) : {{form.familyname(value=author.familyname)}}

Livre : {{form.book_list}}

Ver:

 @app.route('/edit_author/', 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) 

El modelo (pegado solo la tabla asociativa y la tabla de autor, gran parte de la columna está fuera de la pregunta)

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

Actualmente me sale este error:

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

Lo que realmente quiero es que el campo de selección muestre el nombre del autor y su número, y devuelva el número de autor a la aplicación (a la función llamada “add_author” en la cabecera).

Gracias.

Tienes dos problemas:

  1. Como Sean Vieira señaló en su respuesta, la query_factory llamada de consulta_factoría debería devolver una consulta, no los resultados.

  2. La query_factory llamada query_factory debe devolver entidades completas, en sus libros de casos, no identificadores de libros. Creo que QuerySelectField debe estar intentando usar los resultados de la consulta como si fueran objetos asignados, pero los identificadores (devueltos como instancias de KeyedTuple) no lo son.

Creo que esta es la forma correcta de codificar la función de callback:

 def possible_book(): return Book.query 

Un posible problema es que wtforms.ext.sqlalchemy.fields.QuerySelectField espera un objeto de consulta SQLAlchemy, no una lista materializada. Simplemente elimine la llamada all() de su retorno de possible_book libro para devolver una consulta sin materializar a WTForms:

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