Django表单向导 - 为每个步骤定制表单布局

时间:2012-06-23 11:40:16

标签: django django-forms django-templates django-formwizard

目前我正在尝试使用django表单向导。基本设置现在可以工作,我可以为显示变量文本的每个步骤调用不同的模板。

现在我想更进一步,为每一步创建一个自定义的表单布局。 Django的文档显示了一种显示表单的通用方法,始终采用垂直对齐方式。

在我的实验中,我有两个步骤:

  • 第1步:电子邮件和密码(只需要两个需要垂直对齐的字段)
  • 第2步:个人资料:地址,专业,......

因此,对于第2步,我想使用完整的不同表单布局,然后步骤1:使用字段集,字段的水平对齐(例如地址:街道和数字),...

从django文档开始,我认为以下内容可以正常工作(尚未测试):

{% block content %}
# block step: variable text for each step
{% block step %}{% endblock %}
<p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p>
<form action="" method="post">{% csrf_token %}
<table>
{{ wizard.management_form }}
{% if wizard.form.forms %}
    {{ wizard.form.management_form }}
    {% for form in wizard.form.forms %}
        # block form_if: shows a complete customized form layout for each step
        {% block form_if %}{% endblock %}
    {% endfor %}
{% else %}
    # block form_else: shows a complete customized form layout for each step
    {% block form_else %}{% endblock %}
{% endif %}
</table>
{% if wizard.steps.prev %}
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">{% trans    "first step" %}</button>
<button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "prev step" %}</button>
{% endif %}
<input type="submit" value="{% trans "submit" %}"/>
</form>
{% endblock %}

但我遇到的问题是我有两个blocksform_ifform_else调用相同的表单布局。那么我对表单布局进行了双重维护。

有没有更好的方法来实现我想要实现的目标?

谢谢!

亲切的问候

4 个答案:

答案 0 :(得分:2)

根据Rohan的输入和post,我找到了一个有效的解决方案:

我的base_wizard模板如下所示:

<form enctype="multipart/form-data" action="" method="post">{% csrf_token %}
    <table>
        {{ wizard.management_form }}
        {% if wizard.form.forms %}
            {{ wizard.form.management_form }}
            {% for form in wizard.form.forms %}
                <!-- block below accesses a customized form layout for each step -->
                {% block form_if %}{% endblock %}
            {% endfor %}
        {% else %}
            <!-- block below accesses a customized form layout for each step -->
            <!-- using the with statement makes it possible to use the same layout used in the form_if block -->
            {% with form=wizard.form %}
            {% block form_else %}{% endblock %}
            {% endwith %}
        {% endif %}
    </table>
    {% if wizard.steps.prev %}
    <button name="wizard_goto_step" value="{{ wizard.steps.first }}" class="button">{% trans "first step" %}</button>
    <button name="wizard_goto_step" value="{{ wizard.steps.prev }}" class="button">{% trans "prev step" %}</button>
    {% endif %}
    <div>
        <input type="submit" value="{% trans "submit" %}" class="button"/>
    </div>  
</form>

并在每个步骤的模板中使用以下代码:

{% extends "base_wizard.html" %}

{% block form_if %}{% block form_else %}
    <fieldset>
        <legend>Title</legend>
        <div>
            <label>{{ form.field.label }}:<p class="note">{{ form.field.help_text }}</p></label> {{ form.field }}
            <p class="error">
                {% if form.field.errors %}
                    {% for error in form.field.errors %}
                        {{ error }}
                    {% endfor %}
                {% endif %}
            </p>
        </div>
    </fieldset>
{% endblock %}{% endblock %}

使用此功能可以每步只维护一个表单布局,而不是两个。

答案 1 :(得分:1)

您可以为每个步骤创建不同的模板。模板可以根据需要生成html。

要告诉django为步骤使用不同的表单模板,您可以按照这个...

class TestFormWizard(SessionWizardView):

    def get_template_names(self):
        if self.steps.current == 1:
            return 'step1_form.html'
        if self.steps.current == 2:
            return 'step2_form.html'
        return 'wz_form.html'

您可以根据需要定义step1_form.html,step2_form.html等。 提示:对于模板中的常用代码(即管理表单字段),创建不同的模板并将其包含在每个步骤表单中。

答案 2 :(得分:1)

在这种情况下,你可以在模板中使用'with'语句。 类似于:在block_if和block_else中将表单称为myform。

{{ wizard.management_form }}
{% if wizard.form.forms %}
    {{ wizard.form.management_form }}
    {% for form in wizard.form.forms %}
        # block form_if: shows a complete customized form layout for each step
        {% with myform=form %}
        {% block form_if %}{% endblock %}
        {%e endwith %}
    {% endfor %}
{% else %}
    # block form_else: shows a complete customized form layout for each step
    {% with myform=form %}    
    {% block form_else %}{% endblock %}
    {% endwith %}
{% endif %}

答案 3 :(得分:0)

尝试一下crispy-forms。简而言之,您将在表单上设置helper实例属性,这些属性几乎可以控制您在构建表单时无需触及模板代码即可实现的大部分内容。

在某些情况下,如果您最终必须亲自手动编写整个标记,则自定义表单的演示文稿会产生难以处理的模板。在这里,您可以在应用程序的form_helpers.py模块中隔离和构建混乱。

如果您可以使用crispy-forms在创建表单布局方面提供的内容,您将看到需要定义大约10行代码,表单帮助程序的布局会使您有​​数十行和几十行否则你必须维护的模板代码。

在您的情况下最终会有多个表单,每个特定表单的表单帮助程序实例和一个只调用crispy-form标记的模板,以呈现向导为每个步骤提供的表单。< / p>