2016-08-19 46 views
2

我在我的金字塔应用程序中使用wtforms_sqlalchemy并定义几个QuerySelectField s。查询工厂使用导入的DBSession对象进行查询。使用WTForms QuerySelectField与金字塔1.7的数据库会话

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) 

金字塔1.7引入了一个新的SQLAlchemy scaffold,它将db会话对象附加到每个请求。使用新的脚手架mymodel_choices必须使用我的视图中的request来访问数据库会话。该字段虽然不具有对请求对象的访问权限,但不知道用它来调用工厂。

我的想法是直接从视图更新query_factory,但这似乎不是一个合理的方式来做到这一点。当db会话是请求对象的一部分时,我怎样才能使用QuerySelectField

回答

1

query_factory只规定默认查询使用,但QuerySelectField will prefer the query property if it is set.这对金字塔很有用,它不鼓励直接与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) 
+1

使用python2,super()方法不像这样写,使用** super(Form,self).__ init __(** kwargs)** –

+0

@ JérômePigeot自然就是这样,只是大卫主义认为你没有使用过时的Python版本;) –

1

你可以尝试这样的事情(虽然它不是最干净的解决方案)

from myapp.models import MyModel 
from pyramid import threadlocal 

def mymodel_choices(request=None): 
    request = request or threadlocal.get_current_request() 
    choices = request.DBSession.query(MyModel) 
    return choices 

的更多详细信息,请参阅:​​

+0

我已经检查过这个优先级,但文档说这是一种避免的可能性,用户应该只是用它来进行测试。无论如何谢谢 –

+0

@JérômePigeot我相信wtforms并不是真正为此设计的。 –

+0

@AnttiHaapala如果是这样的话,这听起来像是我的设计失败。我正在使用wtforms,但几乎所有的表单库都需要相同的需求。我会继续使用炼金术的脚手架:)谢谢 –