WTForms:我似乎无法动态地给QuerySelectField一个默认值 [英] WTForms: I can't seem to dynamically give a QuerySelectField a default value

查看:31
本文介绍了WTForms:我似乎无法动态地给QuerySelectField一个默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个看起来像这样的表格:

I have a form which looks sort of like this:

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'type'.有人知道我该如何解决吗?

As you can see I am trying to set this up to give a sensible default for the product_type when the form is loaded. However, while this kind of code worked for setting a title as an example, it isn't working for the QuerySelectField 'type'. Does anybody have any ideas how I could fix this?

假设这不可能,有人知道我如何动态地向表单添加表单元素吗?

Supposing that this isn't possible, does anybody know how I could dynamically add form elements to a form?

推荐答案

要在WTForms的QuerySelectField中定义默认值,可以直接在字段定义中进行设置:

To define a default value in a QuerySelectField of WTForms, you can do it directly in the field definition:

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())

但是,它看上去并不简单.考虑到这一点:

However, it is a little less simple than what it looks. Take this into account:

  • 默认值必须为 callable
  • 此可调用对象必须返回模型的对象实例(不是其pk,而是整个对象)
  • 仅在不使用 obj formdata 初始化表单实例时使用(在两种情况下,默认值都将被忽略)
  • The default value must be a callable
  • This callable must return an object instance of your model (not its pk, but the whole object)
  • It will only be used if no obj or formdata is used to initialize the form instance (in both cases, the default value is ignored)

在您的情况下,由于要使用初始化时不具备的obj属性来初始化默认值,因此可以改用工厂:

In your case, since you are initializing the default value using an attribute of your obj that you don't have at hand at initialization time, you may use a factory instead:

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

这里有一个根据参数组成表单的函数(在这种情况下,您不需要默认值是可调用的):

Here you have a function that composes the form according to the parameters (in this case you don't need the default being a callable):

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

ps.表单工厂的好处是您可以在运行时动态处理表单,创建字​​段或设置选择.

ps. the benefits of a form factory is that you can dynamically work with forms, creating fields or setting choices at run time.

这篇关于WTForms:我似乎无法动态地给QuerySelectField一个默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆