在Django FormWizard中获取以前输入的信息

时间:2009-08-07 18:30:42

标签: django django-templates django-forms

我正在尝试使用FormWizard创建一个简单的Django多页面表单。表格应该做的是:

  1. 让访问者在表单中输入名字和姓氏。
  2. 继续下一页,输入之前输入的名字和姓氏,此页面上还会有一个字段让访问者输入信息。
  3. 屏幕将被带到Django done.html页面,其中将存储和显示所有信息。
  4. 在第2步中,我无法确定如何显示访问者在步骤1中输入的信息。我正在发布表单的代码以及用于下面步骤1和2的两个模板:

    forms.py

    from django import forms
    from django.shortcuts import render_to_response
    from django.contrib.formtools.wizard import FormWizard
    
    class ContactWizard(FormWizard):
        def done(self, request, form_list):
            return render_to_response('done.html', {
                'form_data': [form.cleaned_data for form in form_list],
            })
    
        def get_template(self, step):
            return 'buydomain/templates/reg%s.html' % step
    
    class Form1(forms.Form):
        firstName = forms.CharField()
        lastName = forms.CharField()
    
    class Form2(forms.Form):
        message = forms.CharField(widget=forms.Textarea)
    
    步骤1的

    模板:

    {% block content %}
    <p>Step {{ step }} of {{ step_count }}</p>
    <form action="." method="post">
    <table>
    {{ form }}
    </table>
    <input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
    {{ previous_fields|safe }}
    <input type="submit">
    </form>
    {% endblock %}
    

    第2步的模板:

    {% block content %}
    <p>Step {{ step }} of {{ step_count }}</p>
    
    
    {% comment %}
    Show values entered into Form1 here !
    {% endcomment %}
    
    <form action="." method="post">
    <table>
    {{ form }}
    </table>
    <input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
    {{ previous_fields|safe }}
    <input type="submit">
    </form>
    {% endblock %}
    

    如果我有点不清楚我想要实现什么,我很抱歉,我希望等待有人提供解决方案。提前谢谢。

3 个答案:

答案 0 :(得分:6)

首先是一些一般建议 - 如果你不理解如何在Django中使用某些东西,请拉出该文本编辑器并查看代码。它并不总是获得答案的最快方式,但我认为从长远来看它会带来红利。

尝试通过覆盖FormWizard子类中的process_step来添加一些extra_context到第二步。以下是FormWizard(django 1.1)中的注释:

 def process_step(self, request, form, step):
        """
        Hook for modifying the FormWizard's internal state, given a fully
        validated Form object. The Form is guaranteed to have clean, valid
        data.

        This method should *not* modify any of that data. Rather, it might want
        to set self.extra_context or dynamically alter self.form_list, based on
        previously submitted forms.

        Note that this method is called every time a page is rendered for *all*
        submitted steps.
        """
        pass

所以在你自己的ContactWizard类中,类似的东西(注意:我没有运行它):

class ContactWizard(FormWizard):
    def process_step(self,request,form,step):
        if step == 1:
            self.extra_context = {'whatever': form.whatever_you_want_from_the_form}
            return
        else:
            return

答案 1 :(得分:4)

Toby Panzer的回答不允许表单类访问额外的上下文数据 - 只有表单上显示的模板才有权访问。那就是说,听起来这可能就是你所需要的。但是,如果您需要表单来访问,我通过覆盖get_form_kwargs解决了这个问题。它通常只返回一个get_form填充的空字典,因此通过覆盖它来返回包含您需要预先填充的数据的字典,您可以将kwargs传递给表单init。

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 方法中,您可以在调用super之前弹出kwarg:

self.your_data = kwargs.pop('client', None)

答案 2 :(得分:3)

我不知道发布此解决方案是否有用。然而。当您向向导提供dict形式的额外属性时,可以轻松访问向导使用的不同形式(步骤)之间的内容。像这样:

class WizardRegistration(FormWizard):
    def __init__(self, *args, **kwargs):
        super(WizardRegistration, self).__init__(*args, **kwargs)

        setattr(self, 'chosen', {})

在这些步骤之间,您可以轻松地获取表单或模型并存储它,直到您到达done()方法。存储表单值

self.chosen['something_to_store'] = form.cleaned_data.get('a_form_value')

甚至获取/更改/保存模型:

object = Model.objects.get('some_query')

if self.chosen['object']:
    self.chosen['object'].string = 'Something stringy'
    self.chosen['object'].save()