Django 1.1 FormWizard, Динамическое расширение формы

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

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

Eg

Страница 1 - Выберите интересующие темы:

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

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

транжира


person Community    schedule 26.12.2009    source источник
comment
Вам нужно изменить количество шагов в мастере формы или просто изменить форму на странице 2?   -  person JudoWill    schedule 26.12.2009


Ответы (2)


Спендер,

По крайней мере, на данный момент я не знаю, как объединить несколько форм на одной странице в 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

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

person JudoWill    schedule 26.12.2009

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

self.form_list[1] = RelatedQForm(chosen_subs)

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

object is not callable

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

person memyself    schedule 26.01.2011