【问题标题】:Get previously entered information in Django FormWizard获取之前在 Django FormWizard 中输入的信息
【发布时间】:2010-11-17 19:04:10
【问题描述】:

我正在尝试使用 FormWizard 创建一个简单的 Django 多页表单。表单应该做的事情如下:

  1. 让访问者在表单中输入名字和姓氏。
  2. 继续下一个页面,将显示之前输入的名字和姓氏,此页面上还会有一个字段让访问者输入消息。
  3. 访问者将被带到 Django done.html 页面,所有信息都将在其中存储和显示。

在第 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 %}

如果我对我想要实现的目标有些不清楚,我深表歉意,我希望等待有人提供解决方案。提前致谢。

【问题讨论】:

    标签: django django-templates django-forms


    【解决方案1】:

    首先只是一些一般性建议 - 如果您不了解如何在 Django 中使用某些东西,请拿出那个文本编辑器并查看代码。这并不总是获得答案的最快方法,但我相信从长远来看它会带来好处。

    尝试通过覆盖 FormWizard 子类中的 process_step 来为第二步添加一些额外的上下文。以下是 FormWizard (django 1.1) 中的 cmets:

     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
    

    【讨论】:

    • 后续表单类如何访问extra_context数据?
    • extra_contextFormWizard 传递给模板进行渲染。
    • 我仍然赞成这个答案,但想告诉其他人,从 django 1.4 开始,process_step 方法签名更改为仅传递表单对象。正如@bpoetz 所说,请与文档坐在一起阅读它们以找到适合您需求的解决方案。
    【解决方案2】:

    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)
    

    【讨论】:

      【解决方案3】:

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

      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()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-09
        • 2011-01-22
        • 2019-01-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多