我在我的金字塔应用程序中使用wtforms_sqlalchemy并定义了几个QuerySelectField
。查询工厂使用导入的DBSession
对象进行查询。
from wtforms.form import Form
from wtforms_sqlalchemy.fields import QuerySelectField
from myapp.models import DBSession, MyModel
def mymodel_choices():
choices = DBSession.query(MyModel)
return choices
class MyForm(Form):
mymod = QuerySelectField(u'Field', query_factory=mymodel_choices)
Pyramid 1.7引入了一个新的SQLAlchemy脚手架,它将db会话对象附加到每个请求。使用新的脚手架mymodel_choices
必须使用我视图中的request
来访问数据库会话。该字段虽然无法访问请求对象,但也不知道用它来调用工厂。
我的想法是直接从视图更新query_factory
,但这似乎不是一种合乎逻辑的方式。当db会话是请求对象的一部分时,如何使用QuerySelectField
?
答案 0 :(得分:1)
你可以尝试这样的事情(虽然它不是最干净的解决方案)
{{1}}
有关详细信息,请参阅:http://docs.pylonsproject.org/projects/pyramid/en/latest/api/threadlocal.html
答案 1 :(得分:1)
query_factory
仅指定要使用的默认查询,但QuerySelectField
will prefer the query
property if it is set.这对Pyramid非常有用,它不鼓励直接与threadlocal
进行交互。
更改工厂以接受数据库会话。将query
设置为使用请求的db会话调用工厂的结果。
def mymodel_choices(session):
return session.query(MyModel)
f = MyForm(request.POST)
f.mymod.query = mymodel_choices(request.db_session)
由于这有点不方便,您可以创建一个Form
的子类,它接受request
,提取相应的表单数据,并使用请求调用每个QuerySelectField's
查询工厂
class PyramidForm(Form):
def __init__(self, request, **kwargs):
if 'formdata' not in kwargs and request.method == 'POST':
kwargs['formdata'] = request.POST
super().__init__(**kwargs)
for field in self:
if isinstance(field, QuerySelectField) and field.query_factory is not None and field.query is None:
field.query = field.query_factory(request.db_session)
class MyForm(PyramidForm):
...
f = MyForm(request)