如何在Django Formwizard 1.4中动态重复步骤?

时间:2012-10-24 15:18:11

标签: django django-1.4 formwizard

我正在尝试根据步骤中的复选框有条件地重复Django Formwizard(Django 1.4)中的一个步骤。表单创建一个对象,并有一个复选框(希望)允许他们重复该步骤并使用相同的表单创建同一模型的另一个对象。

我看到了这个答案:Django FormWizard Dynamically Alter form_list但不幸的是我认为它只适用于旧版本的FormWizard。

process_step函数不再具有form_list属性。它也没有当前步骤属性(或步骤属性),但我可以通过表单的QueryDict访问当前步骤。它包含一个表单字典,但我不认为在该字典中插入另一个步骤会做任何事情,不幸的是,因为它是一个字典而不是列表,所以我必须在插入它之后修改每个步骤键。

那么,有没有一种方法可以使用Django 1.4 FormWizard将新步骤添加到表单列表中?

更新 - 开始考虑重写get_next_step(自我,步骤)可能是要走的路,但任何输入都非常感激。

更新#2 - 尝试使用get_next_step,但无法在实例的form_list中插入新表单。并不意味着它不可能 - 想法?

3 个答案:

答案 0 :(得分:0)

好吧,我想出了什么。您可以覆盖get_form_list以将内容插入到表单列表中,但您必须将它们保存在self.form_list中,并且只需返回form_list。就我的目的而言,这没关系,但是如果你也在使用conditional_dict,那么你必须要小心。

def get_form_list(self):
    s = self.storage.current_step                                                                
    s_data = self.get_cleaned_data_for_step(s) or {}                                             
    add_another = s_data.get('add_another', False)                                   
    if add_another is True:                                                                      
        index = self.form_list.keyOrder.index(s)+1                                               
        key = "add_another-{0}".format(index)
        self.form_list.insert(index, key,                                                        
                wizard_forms.Wizard4)                                                   
    form_list = super(Wizard, self).get_form_list()
    return form_list

我可能会稍微清理一下,但这是它的要点。第一对线获得当前步骤并获得用于确定是否在该跟随之后插入另一步骤的标志。如果该标志为真,我们获取表单中当前步骤的索引,向其中添加一个索引,并在该索引处插入(在给定索引之前插入插入)。我们使用基于索引的密钥,这样我们就不会得到重叠的密钥,无论步骤重复多少次。然后,我们将新步骤插入到self.form_list中,以便它在实例范围内,在self上调用get_form_list(具有新的self.form_list),并根据需要返回form_list。

有些注意事项:

  • 你必须使用self.storage.current_step而不是self.steps.current,因为后者导致无限递归。
  • 我们在初始化后使用self.form_list这一事实意味着如果您使用conditional_dict,事情可能会变得有点混乱。也就是说,他们很可能不会,因为conditional_dict为条件分配了密钥,而我们form_list中的密钥都没有变化,只有索引。

嗯,那就是它!显然你需要在done()中添加一些逻辑来弄清楚如何保存这些逻辑,但这些特定于你正在做的事情。

答案 1 :(得分:0)

我发布的上一个答案非常不一致,我认为这是一些奇怪的会话冲突错误,但结果却是因为get_form_list并不总是及时调用需要表单的操作。我将相同的逻辑移到get_next_step中,现在它可以顺利运行。

def get_next_step(self, step=None):
    if step is None:
        step = self.steps.current
    s_data = self.get_cleaned_data_for_step(step) or {}
    add_another = s_data.get('add_another', False)
    if add_another is True:
        index = self.form_list.keyOrder.index(step)+1
        key = "add-another-{0}".format(index)
        self.form_list.insert(index, key,
                wizard_forms.Wizard4)
    return super(Wizard, self).get_next_step(step)

答案 2 :(得分:0)

判决结果是,这是不可能的。我还没有弄清楚为什么它有效有时使用前两个解决方案但是在深入了解表单向导的代码之后,很明显每个请求都重新初始化了实例表单列表(从技术上来说)它是一个新的实例),所以即使你在存储中更新列表,或者在get_form_list()中更新它,也有一些调用直接命中实例变量而不是通过它来访问它get_form_list()并且需要进行一些重大的重构来调整它。

我为这个项目寻找了另一条路线,但可能会尽快为此做点什么。