自定义模板在django formtools中不起作用

时间:2017-02-27 01:57:01

标签: python django django-formwizard

我一直在尝试使用formtools向导在我的Django应用程序中添加多页表单。我需要为每个步骤设置自定义表单。共有2个步骤。这是我的代码:

views.py

TEMPLATES = {"initial": "my_app/form_initial.html",
         "final": "my_app/form_last.html"}


class ModelCreateView(SessionWizardView):
    model = MyModel
    template_name = "my_app/model_form.html"
    file_storage =      
    FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'custom'))

    def get_template_names(self):
        return [TEMPLATES[self.steps.current]]

程序my_app / model_form.html

{% extends "my_app/base.html" %}

{% block extra_css %}
{{ wizard.form.media }}
{% endblock %}

{% block content %}
<form action="" method="post">
{% csrf_token %}
    {{ wizard.management_form }}
    <h1>{{ wizard }}</h1>
    {% if wizard.form.forms %}
        <h1>{{ wizard.form.forms }}</h1>
        {{ wizard.form.management_form }}
        {% for form in wizard.form.forms %}
            {{ form }}
        {% endfor %}
    {% else %}
        {{ wizard.form }}
    {% endif %}
    <input type="submit" value="submit"/>
</form>
{% endblock content %}

程序my_app / form_initial.html

 <-- custom form template for step 1 -->

程序my_app / form_last.html

 <-- custom form template for step 2 -->

如果我理解正确,自定义表单模板将替换

{{ form }}
被调用的基本模板中的

标记(my_app / model_form.html)。

我的问题是,使用当前代码,直接调用my_app / form_initial.html。

此外,如果我试图加入

{{ wizard.management_form }}

在my_app / form_initial.html中并附上必要的表单元素,在提交时,它只是重新加载当前页面而不是将我带到my_app / form_last.html

请告诉我这里我做错了什么。

更新:我通过正确扩展基本表单模板修复了自定义模板的问题。但现在当我提交第一步时,同一步骤页面重新加载而不是进入下一步。请让我知道如何调试它?

更新2 :我尝试了更多调试并发现了这一点,即使帖子请求包含字段,我的字段也没有得到验证,form.is_valid()返回false。 form.errors表示所有字段均为missing

3 个答案:

答案 0 :(得分:0)

我让我的应用程序中的向导工作了一个额外的元组列表来映射表单。试试这个,看它是否有效。

WIZARD_FORMS = [("initial", InitailFormName),
                ("final" , FinalFormName),
            ]

TEMPLATES = {"initial": "my_app/form_initial.html",
             "final": "my_app/form_last.html"}


class ModelCreateView(SessionWizardView):
    model = MyModel
    template_name = "my_app/model_form.html"
    file_storage =      
    FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'custom'))

    def get_template_names(self):
        return [TEMPLATES[self.steps.current]]

答案 1 :(得分:0)

我实施模板的方法存在2个问题。

  1. 我假设一旦在视图中定义了基本模板,自定义步骤表单模板就会被替换。执行此操作的正确方法是定义基本模板模板并将其扩展到自定义步骤模板中。
  2. 例如:

    base_form_template.html

    {% block content %}
    <form style="height:inherit;" action="" method="post">
    {% csrf_token %}
        {{ wizard.management_form }}
        {{ wizard.form.errors}}
        {{ wizard.form.non_field_errors}}
        {% block custom_form %}
        {% endblock %}
    </form>
    {% endblock content %}
    

    step1.html

    {% extends "my_app/base_form_template.html" %}
    
    <-- custom form template code goes here -->
    

    step2.html

    {% extends "my_app/base_form_template.html" %}
    
    <-- custom form template code goes here -->
    
    1. 在我的自定义表单模板中,输入字段的name属性需要设置为wizard.form.<model_attribute>.html_name。这很难找到。我最初只是设置它wizard.form.<model_attribute>,并想知道为什么它不起作用。做了一些挖掘并找到了这个。 html_name<step_name>_<field_name>格式不同。现在看一下,有这样的名字是有意义的。

答案 2 :(得分:0)

Keval说的是正确的-导致self.cleaned_data['field']为空的主要问题是我需要使用form.field.html_name而不是form.field.name作为模板的名称字段。

但是,从所提供的文档中还不清楚。这是我的模板页面的摘录,因此更加清晰:

<div class="form-group">
  <label>{{ form.account_name.label }}</label>
  <input name="{{ form.account_name.html_name }}"
         value="{{ form.account_name.value|default_if_none:'' }}"
         class="form-control">
</div>