Python 将WTForms QuerySelectField与Pyramid 1.7';数据库会话

Python 将WTForms QuerySelectField与Pyramid 1.7';数据库会话,python,sqlalchemy,pyramid,wtforms,Python,Sqlalchemy,Pyramid,Wtforms,我在金字塔应用程序中使用wtforms\u sqlalchemy,并定义了几个QuerySelectFields。查询工厂使用导入的DBSession对象进行查询 from wtforms.form import Form from wtforms_sqlalchemy.fields import QuerySelectField from myapp.models import DBSession, MyModel def mymodel_choices(): choices = D

我在金字塔应用程序中使用wtforms\u sqlalchemy,并定义了几个
QuerySelectField
s。查询工厂使用导入的
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)
Pyramid1.7引入了一个新的SQLAlchemy脚手架,它将db会话对象附加到每个请求。使用新的scaffold
mymodel\u选项
必须从我的视图中使用
request
来访问db会话。但是该字段没有访问请求对象的权限,并且不知道如何使用它调用工厂


我的想法是直接从视图中更新
query\u factory
,但这似乎不是一种合乎逻辑的方法。当db会话是请求对象的一部分时,如何使用
QuerySelectField

您可以尝试类似的方法(尽管这不是最干净的解决方案)


有关更多详细信息,请参见:

query\u factory
仅指定要使用的默认查询,但这对Pyramid很有用,因为Pyramid不鼓励直接与
threadlocal
交互

更改工厂以接受db会话。将
query
设置为使用请求的db会话调用工厂的结果

def mymodel_choices(session):
    return session.query(MyModel)

f = MyForm(request.POST)
f.mymod.query = mymodel_choices(request.db_session)
由于这有点不方便,您可以创建
表单
的子类,它接受
请求
,提取适当的表单数据,并使用请求调用每个
QuerySelectField的
查询工厂

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)

我已经检查了优先级,但是文档中说这是一种可以避免的可能性,用户应该使用它进行测试。谢谢anyway@JérômePigeot我相信wtforms并不是专门为此而设计的。@AnttiHaapala如果是这样的话,对我来说这听起来像是设计上的失败。我正在使用wtforms,但几乎所有的表单库都需要相同的需求。我将继续使用旧式炼金术脚手架:)谢谢
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)