2012-04-06 67 views
1

我有一种形式,看起来有点像这样:WTForms:我似乎无法动态地给一个QuerySelectField默认值

class AddProductForm(Form): 
    title = TextField('Title') 
    type = QuerySelectField('Type', 
     query_factory=lambda: ProductType.query.order_by(ProductType.sequence).all()) 

    def __init__(self, formdata=None, obj=None, prefix='', **kwargs): 
     try: 
      product_type_id = ProductType.query.filter_by(name=obj['product_type']).one().product_type_id 
      kwargs.setdefault('type', product_type_id) 
     except NoResultFound: 
      pass 

     Form.__init__(self, formdata, obj, prefix, **kwargs) 

正如你可以看到我试图设置此给予加载表单时product_type的合理默认值。但是,虽然这种类型的代码用于设置标题作为示例,但它不适用于QuerySelectField“类型”。有没有人有任何想法我可以解决这个问题?

假设这是不可能的,没有任何人知道我怎么能动态添加表单元素的形式?

+0

嗨,你是否同时解决了这个问题? – Ib33X 2013-01-24 13:42:40

回答

2

使用参数,如:

QuerySelectField(allow_blank=True, blank_text=u'-- please choose --', ...) 

可以添加默认选择选项

+0

这正是我所需要的 – Anekdotin 2017-03-20 14:30:55

6

要WTForms的QuerySelectField定义的默认值,你可以在字段定义直接做到这一点:

my_field = QuerySelectField(
    label=u"My Label", 
    query_factory=lambda: Model.query(...), 
    get_pk=lambda item: item.id, 
    get_label=lambda item: item.name, 
    allow_blank=True, 
    default=lambda: Model.query.filter(...).one()) 

但是,它看起来不那么简单。考虑到这一点:

  • 默认值必须是调用
  • 此调用必须返回你的模型的对象实例(不是它的PK,但整个物体)
  • 它只会是如果使用不OBJFORMDATA用于初始化形式实例(在这两种情况下,默认值被忽略)

在您的CA SE,因为你是初始化使用,你不手头有在初始化时您obj的属性的默认值,你可以使用一个工厂来代替:

def add_product_form_factory(default_type_name): 
    class AddProductForm(Form): 
     title = TextField('Title') 
     type = QuerySelectField('Type', 
      query_factory=lambda: ProductType.query.order_by(ProductType.sequence).all(), 
      default=ProductType.query.filter_by(name=default_type_name).one() 
     ) 
    return AddProductForm 

这里有构成上述形式的函数根据参数(在这种情况下,您不需要默认为可调用):

AddProductForm = add_product_form_factory(default_type_name='foo') 
form = AddProductForm() 

ps。表单工厂的好处在于,您可以动态地使用表单,在运行时创建字段或设置选项。

+0

感谢您指出这一点:“只有在没有使用obj或formdata来初始化表单实例时才会使用它(在这两种情况下,默认值都会被忽略)” – PartialOrder 2016-04-28 14:50:03