Django 1.1 FormWizard, Динамически расширяемая форма - PullRequest
1 голос
/ 26 декабря 2009

Я пытаюсь создать многостраничную форму, в которой количество элементов поля на второй странице определяется ответами, данными на первой.

У меня настроен FormWizard, и я понимаю, что мне нужно использовать process_step (), чтобы изменить настройку для следующей страницы. Я могу либо расширить существующее определение формы, чтобы добавить больше элементов, либо объединить 2 или более определений формы вместе, чтобы получить правильное количество элементов формы, но я понятия не имею, как это сделать.

Например

Страница 1 - Выберите заинтересованные предметы:

Страница 2 - по каждому предмету: задавайте соответствующие вопросы. Вопросы определяются как отдельные формы в заявке, но их необходимо показать на одной странице или объединить в одну форму.

Любая помощь очень ценится.

Спендер

Ответы [ 2 ]

1 голос
/ 26 декабря 2009

Спендер,

По крайней мере, на данный момент я не знаю способа объединения нескольких форм на одной странице в FormWizard. В django 1.2 вы сможете включать FormSets как шаги в FormWizards (согласно этой заявке ), но они имеют дело только с несколькими копиями идентичных форм, а не с компиляциями многих форм. Но есть способ сделать то, что вы просите:

from django.contrib.formtools.wizard import FormWizard
from django import forms

class SubjectForm(forms.Form):
    subjects = forms.MultipleChoiceField(choices = (('language', 'language'), 
                                                        ('sport','sport')))

class RelatedQForm(forms.Form):
    """Overload the __init__ operator to take a list of forms as the first input and generate the 
    fields that way."""
    def __init__(self, interested_subjects, *args, **kwargs):
        super(RelatedQForm, self).__init__(*args, **kwargs)
        for sub in interested_subjects:
            self.field[sub] = forms.CharField(label = "What do you think about %s" % subject)

class SubjectWizard(FormWizard):
    def done(self, request, form_list):
        process_form_list(form_list)

    def process_step(self, request, form, step):
        if step == 1:
            chosen_subs = form.cleaned_data['subjects']
            self.form_list[1] = RelatedQForm(chosen_subs)

С помощью этого кода вы создаете экземпляр FormWizard, как обычно, в представлении, а затем позволяете классу мастера позаботиться обо всем за кадром.

Общая идея - перегрузить класс init класса RelatedQForm для динамического изменения полей. Этот фрагмент кода был взят из здесь . Вы можете сделать обработку в операторе init настолько сложной, насколько захотите, прочитав «включить поля из ваших форм в виде блоков if-elif внутри цикла for» ... вы, вероятно, даже можете подумать Чтобы исключить поля из ваших текущих форм программно, мне нужно было бы их увидеть, чтобы понять это.

Ваша функция "process_form_list" должна будет перебирать поля, используя что-то вроде:

for field, val in form.cleaned_data.items():
    do_stuff

Надеюсь, это поможет вам:)

0 голосов
/ 27 января 2011

Я не думаю, что

self.form_list[1] = RelatedQForm(chosen_subs)

часть работ. Я всегда получаю сообщение об ошибке:

object is not callable

Похоже, что form_list принимает только RelatedQForm (имя формы), а не его экземпляр.

...