2016-07-05 1 views
1

私はこのフラスコのアプリケーションを作成しています。前のフォームで定義された変数を別のフォームに渡す

あなたがフラスコ内にフォームを定義するとき、あなたは次のことをやる、ほとんどの時間:

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 
    ... 

私がこれまで試したどのような:

  • セッション['dm_choices']は私にworking outside of request contextエラーを返します
  • グローバル変数は何らかの理由でリセットされます
  • __init__はフォームを追加することでフォームにオーバーロードされますが、__init__機能の上の部分ではアクセスできません。

これはすべて同じページにある必要があります。

array_of_choicesDataMappingFormクラスに渡す方法はありますか?

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' 
+0

ページをリロードせずにフォームを動的にする必要がありますか? Flaskはサーバーサイドコードのみを処理し、クライアント側のダイナミクスはjavascriptが必要です。 – syntonym

+0

いいえ、私はページリロードを使用しています。つまり、同じページ(リロード後)の最初のページを参照すると、2番目のフォームが表示されます。 –

+0

セッションのアプローチと '__init__'のオーバーロードは、作業。具体的なコードを教えていただけますか? [Here](http://wtforms.simplecodes.com/docs/1.0.1/specific_problems.html#dynamic-form-composition)は、動的フォームに関するドキュメントです。 – syntonym

答えて

0

私はそれを持っている:

EDITは、これは私が__init__過負荷をTRIDときのように見えたものです!あなたの最後のリンクで正しい方向に私を指して@シノニムに感謝します。

あなたがする必要があるのは、クラスが定義されている関数を宣言することだけです。変数を関数に渡すと、クラス内で変数にアクセスできます。

最後に、関数をフォームオブジェクトに戻します。

例:

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')] 
0

あなたが動的に動作するはずです以下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 

この場合、フォームは必要なだけカスタマイズできます。もちろん、選択肢をカスタマイズしたいだけの場合は、最初のアプローチで十分です。

+0

ああそうだった!私が欠けていた部分は 'self.DMpatient_id.choices = choices'でした。ご協力いただきありがとうございます。私がちょうど投稿した方法もbtwの作品です。それを使うのに間違ったことは何ですか? –

+0

私はそれがあなたの方法を動作させる限り良いと思います。 「通常は」クラスを動的に作成しないので、後でその選択肢を変更する可能性が追加されたのかもしれません。 – syntonym

+0

よろしくお願いします。助けてくれてありがとう ! –

関連する問題