5

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

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

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

那么,有没有一种使用 Django 1.4 FormWizard 向表单列表中添加新步骤的好方法?

更新——开始认为覆盖 get_next_step(self, step) 可能是要走的路,但任何输入都非常感谢。

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

4

3 回答 3

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() 中添加一些逻辑来弄清楚如何保存每一个,但这特定于您正在做的任何事情。

于 2012-10-25T15:00:22.750 回答
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)
于 2012-10-26T16:42:49.163 回答
0

结论是,这是不可能的。我还没有完全弄清楚为什么它有时会与前两种解决方案一起工作,但是在深入研究表单向导的代码之后,很明显每个请求都会重新初始化实例表单列表(嗯,从技术上讲,它是一个新实例),并且因此,即使您在存储中更新列表,或在 get_form_list() 中更新它,也有一些调用直接命中实例变量而不是通过 get_form_list() 访问它,并且需要进行一些重大的重构来调整它。

我为这个项目选择了另一条路线,但可能很快会尝试为此组合一些东西。

于 2012-11-01T01:16:23.197 回答