如何在 formtool 向导的一个步骤中手动重置数据?

How to manually reset the data in a step of a formtool wizard?

我有一个向导,其中的几个步骤组织如下:

1 -> 2 -> 3 -> 4 -> 6
          |         ^
          |         |
           --> 5 ---

其中第 6 步只是回顾前面步骤中的数据。第 4 步和第 5 步是互斥的。

如果用户以 1、2、3、4、6 的形式旅行,然后决定使用 5 而不是 4,我希望能够在步骤 4 中重置数据。 如何手动重置已为向导的第 4 步(或任何步骤)存储的数据?

这在 django-formtools 中并没有真正的记录,但是你会发现 WizardView 有一个 属性 self.storage 这是 BaseStorage 的一个实例( 'formtools.wizard.storage.base')。

self.storage.data是所有存储数据的字典。直接操作这个字典有点危险,最好使用方法self.storage.set_step_data(step, data)来更改特定步骤的数据:

self.storage.set_step_data('4', {})

将清空步骤“4”的数据。

注意:如果您还上传文件,您应该删除它们,这有点棘手,因为如果 files 为空({}).查看该方法以覆盖它或查看如何从数据字典中删除文件。

正如在对 dirkgroten 的回答的评论中所讨论的,我在表单向导中有一个 step,它是一个 formset。对于此特定步骤,每次使用 stepstep 的信息时,使用 self.storage.set_step_data(step, {}) 都会导致错误,因为正如 dirkgroten 在他的评论中指出的那样, [=16] 的信息=] 在手动设置 step 的数据后丢失。

因此,我最终只是简单地从 self.storage 中删除 stepkey - value 对。通过这样做,我得到了表单向导的正常行为,例如self.get_cleaned_data_for_step(step) returns None 如果 step 不在 self.storage 中并且 formset 在删除 [ 后使用 step 时正确启动=11=] 来自 self.storage

要从 self.storage 中删除 step,我在 formwizard 中使用了 process_step 方法。

def process_step(self, form):
    """ Process the form after step data is submitted and validated by jQuery.  """
 #--> Get form prefix
    prefix = form.prefix
 #--> Action per step
    if prefix == 'e':
     #--> Set previous experiment
        try:
            exp_save = self.get_cleaned_data_for_step('e')
            if exp_save is None:
                pass
            else:
                exp_save = exp_save['e_exp'].id
        except KeyError:
            exp_save = None
     #--> Get selected experiment
        exp_sel = form.cleaned_data['e_exp'].id
     #--> Compare and delete steps if needed
        if exp_save is None:
            pass
        else:           
            if exp_sel == exp_save:
                pass
            else:
                for stepN in self.delStep[exp_sel]:
                 #--> self.delStep is a dict with the steps to be deleted for each exp_sel
                    if stepN in self.storage.data['step_data'].keys():
                     #--> Remove the key-value pair from data and files if there is already something to delete
                        del self.storage.data['step_data'][stepN]
                        del self.storage.data['step_files'][stepN]
                    else:
                        pass                
    else:
        pass
 #--> Return as implemented in the base class
    return self.get_form_step_data(form)
#---

当然,正如 dirkgroten 所提到的,这不会删除剩余文件。