Django 表单向导 - 每个步骤的自定义表单布局
Posted
技术标签:
【中文标题】Django 表单向导 - 每个步骤的自定义表单布局【英文标题】:Django form wizard - customized form layout for each step 【发布时间】:2012-06-25 12:29:44 【问题描述】:目前我正在尝试使用 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_if
和form_else
调用相同的表单布局。因此,我对表单布局进行了双重维护。
有没有更好的方法来实现我想要实现的目标?
谢谢!
亲切的问候
【问题讨论】:
如果您在每个步骤中只显示一个表单,那么您只需要 form_else。在这种情况下,您可以显着简化您的模板。不能吗? 【参考方案1】:根据 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 %
使用它可以在每个步骤中只维护一个表单布局,而不是两个。
【讨论】:
【参考方案2】:您可以为每个步骤创建不同的模板。模板可以根据需要生成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 等。 提示:对于模板中的通用代码(即管理表单字段),创建不同的模板并将它们包含在每一步表单中。
【讨论】:
您好 Rohan,谢谢您的反馈。事实上,我已经为每个步骤调用了不同的模板。每个都在我的代码中用特定的形式填充block form_if
和block form_else
标记。但是目前我在模板中复制了两次表单(每个块一个),因为我不能在模板中使用相同的块两次 => 给出错误。结果是双重维护。如果您对此有解决方案,我将不胜感激 :) 干杯!【参考方案3】:
在这种情况下,您可以在模板中使用“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 %
【讨论】:
【参考方案4】:试试看crispy-forms。简而言之,您将在表单上设置一个 helper
实例属性,该属性几乎可以控制您想要通过构建表单来完成的大部分工作,而无需触及模板代码。
在某些情况下,如果您最终不得不自己手动编写整个标记,那么自定义表单的呈现方式会产生笨拙的模板。在这里,您可以在应用程序的 form_helpers.py
模块中隔离和构建混乱。
如果您可以使用crispy-forms
在创建表单布局方面提供的内容,您会发现定义表单助手布局所需的大约 10 行代码使您摆脱了数十行模板代码否则你必须维护。
在您的情况下,您最终会得到多个表单、每个特定表单的表单帮助程序实例和一个仅调用 crispy-form
标记以呈现向导为每个步骤提供的表单的模板。
【讨论】:
嗨 Filip,谢谢您的输入。不完全是我正在寻找的答案,但我肯定会检查这个应用程序。谢谢!以上是关于Django 表单向导 - 每个步骤的自定义表单布局的主要内容,如果未能解决你的问题,请参考以下文章