12

動的フォームを作成できるように、最初のフォームのデータを 2 番目のフォームのコンストラクターに渡す必要がある FormWizard があります。

FormWizard の process_step を介して最初のフォームのデータを取得できます。

フィールドのリストのデータベース呼び出しを使用して、2 番目のフォームのフィールドを作成します。

class ConditionWizardDynamicQuestions(forms.Form):

    def __init__(self, DynamicQuestions=None, *args, **kwargs):
       super(ConditionWizardDynamicQuestions, self).__init__(*args, **kwargs)
       questions = Question.objects.filter(MYDATA = DATA_FROM_1STFORM)
       for q in questions:
            dynField = FieldFactory(q)
            self.fields[q.label] = dynField

DATA_FROM_1STFORMを渡すにはどうすればよいですか?


結果のコード: フォームのinitを放棄し、CreateQuestions 定義に切り替えました。次に、ウィザードの get_form オーバーライドを使用して、作成後にフォームを変更しました。

class ConditionWizard(SessionFormWizard):
    def get_form(self, request, storage, step=None, data=None, files=None):
        form = super(ConditionWizard, self).get_form(request, storage, step, data, files)
        stepIndex = self.get_step_index(request, storage, step)
        if stepIndex == 1:
            form.CreateQuestions(request.session["WizardConditionId"])
        if stepIndex == 3:
            form.fields['hiddenConditionId'].initial = request.session["WizardConditionId"]
            form.fields['medicationName'].queryset = Medication.objects.filter(condition = request.session["WizardConditionId"])
        return form
4

4 に答える 4

8

WizardView の get_form_kwargs をオーバーライドすることでこれを解決しました。通常は、get_form が入力する空の辞書を返すだけなので、事前入力が必要なデータを含む辞書を返すようにオーバーライドすることで、フォームの init に kwargs を渡すことができます。

def get_form_kwargs(self, step=None):
    kwargs = {}
    if step == '1':
        your_data = self.get_cleaned_data_for_step('0')['your_data']
        kwargs.update({'your_data': your_data,})
    return kwargs

次に、フォームのinitメソッドで、スーパーを呼び出す前に kwarg をポップすることができます。

self.your_data = kwargs.pop('client', None)
于 2012-10-22T15:04:27.077 に答える
5

FormWizard は、前の各フォームのデータを次のフォームに既に渡しています。get_formクラスをインスタンス化するためにそのデータを取得する場合 (たとえば、フォームに必要な特別なキーワード引数がある場合)、フォーム ウィザード クラスをオーバーライドして querydict を取得する方法があります。例えば:

class SomeFormWizard(FormWizard):
    def get_form(self, step, data=None):
        if step == 1 and data: # change this to whatever step requires
                               # the extra data
            extra_data = data.get('key_from_querydict')
            if extra_data:
                return self.form_list[step](data,
                                            keyword_argument=extra_data,
                                            prefix=self.prefix_for_step(step),                                                                                                                                            
                                            initial=self.initial.get(step, None))
        # Fallback for the other forms.
        return self.form_list[step](data,
                                    prefix=self.prefix_for_step(step),                                                                                                                                            
                                    initial=self.initial.get(step, None))

parse_params(self, request, *args, **kwargs)ビューで行うのと同じように、FormWizard でオーバーライドして url/request データにアクセスすることもできることに注意してくださいrequest.user。そこからデータを取得することをお勧めします。

お役に立てれば。

于 2010-11-11T17:29:15.827 に答える
0

私は最近、django フォーム ウィザードを使用していましたが、同様の問題を解決していました。データをinitに渡すことはできないと思いますが、できることはinitコンストラクターをオーバーライドすることです。

next_form = self.form_list[1]

# let's change the __init__
# function which will set the choices :P
def __init__(self, *args, **kw):
    super(next_form, self).__init__(*args, **kw)
    self.fields['availability'].choices = ...
next_form.__init__ = __init__

Python では関数を一度に宣言して割り当てることができず、(ラムダを使用しない限り) 名前空間に配置する必要があるのは非常に面倒ですが、まあまあです。

于 2010-10-16T23:52:38.543 に答える