2

目前我正在尝试使用 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 %}

但我在这里遇到的问题是我有两个blocks:form_ifform_else调用相同的表单布局。因此,我对表单布局进行了双重维护。

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

谢谢!

亲切的问候

4

4 回答 4

2

根据 Rohan 的输入和以下帖子,我找到了一个可行的解决方案:

我的 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 %}

使用它可以在每个步骤中只维护一个表单布局,而不是两个。

于 2012-06-24T10:01:45.230 回答
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 %}
于 2012-06-24T08:31:32.247 回答
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 等。提示:对于模板中的通用代码(即管理表单字段),创建不同的模板并将它们包含在每一步表单中。

于 2012-06-23T18:00:56.870 回答
0

试着看看脆的形式。简而言之,您将helper在表单上设置一个实例属性,该属性几乎可以控制您希望通过构建表单来完成的大部分工作,而无需触及模板代码。

在某些情况下,如果您最终不得不自己手动编写整个标记,那么自定义表单的呈现方式会产生笨拙的模板。form_helpers.py在这里,您可以隔离和构建应用程序模块中的混乱。

如果您可以使用crispy-forms在创建表单布局方面提供的内容,您会发现定义表单助手布局所需的大约 10 行代码使您摆脱了数十行模板代码,否则您必须这样做维持。

在您的情况下,您最终会得到多个表单、每个特定表单的表单帮助程序实例和一个仅调用crispy-form标签以呈现向导为每个步骤提供的表单的模板。

于 2012-06-23T18:12:53.017 回答