More specific SQL query with flask-wtf queryselectfield

天涯浪子 提交于 2019-12-11 07:44:39

问题


I'd like to create a Login-Form using Flask and WTF. The application should read the nicknames of all users out of a database-table and display them in a QuerySelectField.

It does work - but I think that I can do it in a 'nicer way'...

I have a database table like this:

 id | nickname  |    fullname    |          email
----+-----------+----------------+--------------------------
  1 | Admin     | The Admin      | admin@example.com
  2 | JDoe      | John Doe       | jd@example.com

In my models.py I have the corresponding class User and a function getUser:

from app import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    nickname = db.Column(db.String(64), index=True, unique=True)
    fullname = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)

    def __repr__(self):
        return '<User %r>' % (self.nickname)

# used for query_factory    
def getUser():
    u = User.query
    return u

The forms.py contains the form-class

from flask.ext.wtf import Form
from wtforms import StringField, BooleanField, SelectField
from wtforms.validators import DataRequired, Required
from wtforms.ext.sqlalchemy.fields import QuerySelectField

from .models import User, getUser

class LoginForm(Form):
    openid = StringField('openid', validators=[DataRequired()])
    remember_me = BooleanField('remember_me', default=False)
    user = QuerySelectField(u'User', query_factory=getUser, get_label='nickname')

As I said, all nicknames appear nicely in my QuerySelectField.

<select id="user" name="user"><option value="1">Admin</option><option value="2">JDoe</option></select>

But I wonder about the query that is made:

INFO sqlalchemy.engine.base.Engine SELECT "user".id AS user_id, "user".nickname AS user_nickname, "user".fullname AS user_fullname, "user".email AS user_email
FROM "user"

It seems whole table is returned and i receive unnecessary Data (fullname and email), too. That's what I want to avoid.

How can I query only User.id and User.nickname and display it in QuerySelectField? (Of course I did research - i tryed filter_by or User.query(User.id, User.nickname) - but only got errors about not matched tuples)

Can anyone help?

Thanks in advance!

mycket


回答1:


Not sure which version of SQLAlchemy you are using, but as of 0.9.0 there is sqlalchemy.orm.load_only which can be used to easily return a subset of columns for a query.

You could modify getUser() to something like the following:

from functools import partial
from sqlalchemy import orm

def getUser(columns=None):
    u = User.query
    if columns:
        u = u.options(orm.load_only(*columns))
    return u

def getUserFactory(columns=None):
    return partial(getUser, columns=columns)

# subsequently when defining LoginForm
user = QuerySelectField(u'User',
                        query_factory=getUserFactory(['id', 'nickname']),
                        get_label='nickname')


来源:https://stackoverflow.com/questions/26254971/more-specific-sql-query-with-flask-wtf-queryselectfield

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!