【问题标题】:Passing a variable defined in previous form to another form将先前表单中定义的变量传递给另一个表单
【发布时间】:2016-07-05 13:34:31
【问题描述】:

所以我正在制作这个烧瓶应用程序,我需要一些有关变量访问的帮助。

大多数时候,当您在烧瓶中定义表单时,您会执行以下操作:

class MyForm(Form):
    my_field = StringField('I'm a field')
    my_submit = SubmitField('Go!')

当您需要该表单时,您将使用form = MyForm() 声明该类的一个实例

到这里,一切都很好,但是:

如果您想说SelectField(下拉菜单),其中选项取决于先前表单的答案,您需要能够为新表单提供这些选项。这就是我想要实现的目标,但我无法获取变量来保留其内容。

这是我的表单代码(以上页面代码):

class DataMappingForm(Form):

    dm_choices = #I need this array !

    DMpatient_id = SelectField(u'Select Patient ID Column', 
            choices=dm_choices, validators=[Required()])
    ...

这是我的页面代码:

@app.route('/upload', methods=['GET','POST'])
def upload():
    uform = SomeOtherForm()
    if uform.is_submitted() and uform.data['Usubmit']:
        #Do stuff from previous form
        # and declare array_of_choices
    dmform = DataMappingForm() #Needs array_of_choices to work
    ...

到目前为止我已经尝试过:

  • session['dm_choices'] 给我一个working outside of request context 错误
  • 全局变量,由于某种原因被重置
  • 通过添加数组重载Form的__init__,但我无法在__init__函数上方的部分访问它。

我应该提一下,这一切都需要在同一页面上。

有没有办法将此array_of_choices 传递给我的DataMappingForm 类?

编辑这是我尝试__init__重载时的样子:

class DataMappingForm(Form):
     def __init__(self, dm_choices, *args, **kwargs):
         self.dm_choices = dm_choices
         Form.__init__(self, *args, **kwargs)

     DMpatient_id = SelectField(u'Select Patient ID Column', 
             choices=dm_choices, validators=[Required()])
#I've tried putting it above or below, I get 'dm_choices is not defined'

【问题讨论】:

  • 所以您需要动态表单而不需要重新加载页面? Flask 仅处理服务器端代码,对于客户端动态,您需要 javascript。
  • 不,我正在使用页面重新加载,我的意思是,一旦您引用了第一个表单,第二个表单就会出现在同一页面上(重新加载后)
  • 那么会话和重载__init__ 的方法应该可以工作。能给出具体代码吗? Here 是一些关于动态表单的文档。
  • "全局变量,由于某种原因被重置" 原因是每个请求都是唯一的,可以由单独的进程/线程处理。如果在处理我的请求过程中设置的值影响了其他人的后续请求,那将是非常糟糕的。

标签: python-2.7 flask flask-wtforms


【解决方案1】:

我明白了!感谢@synonym 通过您的最后一个链接为我指明了正确的方向。

您需要做的就是声明一个定义类的函数。然后将变量传递给函数,它可以在类中访问。

最后,让函数返回表单对象。

例子:

def makeMyForm(myArray):
    def class MyForm(Form):
        my_select_field = SelectField(u'I'm a select field', choices=myArray)
        my_submit = SubmitField(u'Go!')
    return MyForm()

要制作表格,请使用:

form = makeMyForm(theArrayYouWant)

然后瞧!

注意:正如我之前遇到的问题,我会提到 Array 是由元组组成的:

myArray = [('value','What you see'),('value2','What you see again')]

【讨论】:

    【解决方案2】:

    如果您想动态更改 SelectField 的选择,以下应该可以工作:

    class DataMappingForm(Form):
    
        def __init__(self, choices)
            self.DMpatient_id.choices = choices
    
        DMpatient_id = SelectField(u'Select Patient ID Column') #note that choices is absent
    

    如果您想要完全动态的字段,您可以在函数中动态创建类。来自WTForms Documentation:

    def my_view():
        class F(MyBaseForm):
            pass
    
        F.username = StringField('username')
        for name in iterate_some_model_dynamically():
            setattr(F, name, StringField(name.title()))
    
        form = F(request.POST, ...)
        # do view stuff
    

    在这种情况下,您可以根据需要自定义表单。当然,如果您只想自定义选项,第一种方法就足够了。

    【讨论】:

    • 哦,原来如此!我缺少的部分是self.DMpatient_id.choices = choices。谢谢你的帮助。我刚刚发布的方式也适用于顺便说一句。使用有什么问题吗?
    • 我认为只要它按你的方式工作就很好。 “通常”不会动态创建类,也许这就是为什么在这种情况下他们增加了稍后修改选择的可能性。
    • 好的,我会记住的。感谢您的帮助!
    猜你喜欢
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多