目前我正在尝试让Django的formtools接受动态的步骤 .

我正在构建一个会计应用程序,我需要一个表单来输入我的交易 . 我有借方和贷方 . 我想添加新步骤,直到所有借记字段中的金额等于所有贷记金额的总和 .

到目前为止,我得到了以下代码:

class TransactionWizard(SessionWizardView):
    form_list = [TransactionCreateForm]

    template_name = 'finance/transaction/create.html'

    post_data = {}

    def done(self, form_list, **kwargs):
        try:
            # Set document_number if not set
            # Save validated data
            document_number = None
            document_number_generated = False
            if self.post_data['0']['document_number'] is None:
                max_document_number = Transaction.objects.filter(document_number_generated=True).aggregate(Max('document_number'))['document_number__max']
                next_document_number =  '1' if max_document_number is None else str(int(max_document_number) + 1)[2:]
                document_number = str(datetime.date.today().strftime('%y')) + next_document_number.zfill(5)
                document_number_generated = True
            # Create transactions from forms
            for key in self.post_data:
                document_number = document_number if document_number else self.post_data[key]['document_number']

                transaction = Transaction()
                transaction.account = self.post_data[key]['account']
                transaction.date = self.post_data[key]['date']
                transaction.document_number = document_number
                transaction.text = self.post_data[key]['text']
                transaction.debit = self.post_data[key]['debit']
                transaction.credit = self.post_data[key]['credit']
                transaction.cost_center = self.post_data[key]['cost_center']
                transaction.cost_object = self.post_data[key]['cost_object']
                transaction.document_number_generated = document_number_generated
                transaction.save()

            messages.success(self.request, _('Transaction %s created successfully' % document_number))
            self.instance_dict = None
            self.storage.reset()
            self.storage.current_step = self.steps.first
            return HttpResponseRedirect(reverse_lazy('finance:transaction_create'))
        except ValueError as e:
            form_list[-1].add_error(None, e)
            return self.render(form_list[-1])


    def post(self, *args, **kwargs):
        """
        This method handles POST requests.
        The wizard will render either the current step (if form validation
        wasn't successful), the next step (if the current step was stored
        successful) or the done view (if no more steps are available)
        """
        # Look for a wizard_goto_step element in the posted data which
        # contains a valid step name. If one was found, render the requested
        # form. (This makes stepping back a lot easier).
        wizard_goto_step = self.request.POST.get('wizard_goto_step', None)
        if wizard_goto_step and wizard_goto_step in self.get_form_list():
            return self.render_goto_step(wizard_goto_step)
        # Check if form was refreshed
        management_form = ManagementForm(self.request.POST, prefix=self.prefix)
        if not management_form.is_valid():
            raise ValidationError(
                _('ManagementForm data is missing or has been tampered.'),
                code='missing_management_form',
            )
        form_current_step = management_form.cleaned_data['current_step']
        if (form_current_step != self.steps.current and
                self.storage.current_step is not None):
            # form refreshed, change current step
            self.storage.current_step = form_current_step

        # get the form for the current step
        form = self.get_form(data=self.request.POST, files=self.request.FILES)

        # and try to validate
        if form.is_valid():
# if the form is valid, store the cleaned data and files.
            self.storage.set_step_data(self.steps.current, self.process_step(form))
            self.storage.set_step_files(self.steps.current, self.process_step_files(form))

            # Save form data to post_data
            self.post_data.update({
                self.steps.current: 
                    {
                        'account': form.cleaned_data['account'],
                        'date': form.cleaned_data['date'],
                        'document_number': form.cleaned_data['document_number'],
                        'text': form.cleaned_data['text'],
                        'debit': form.cleaned_data['debit'],
                        'credit': form.cleaned_data['credit'],
                        'cost_center': form.cleaned_data['cost_center'],
                        'cost_object': form.cleaned_data['cost_object']
                    }
            })

            # Check if debit=credit. If not render new form, otherwise finish wizard
            debit = Decimal(0)
            credit = Decimal(0)
            #for step in self.form_list:
            for key in self.post_data:
                #data = self.get_cleaned_data_for_step(step)
                if self.post_data[key]['debit'] is not None:
                    debit += Decimal(self.post_data[key]['debit'])
                if self.post_data[key]['credit'] is not None:
                    credit += Decimal(self.post_data[key]['credit'])

            if debit != credit:
                next_step = str(int(self.steps.current) + 1)

                # Get inital data
                #data = self.get_cleaned_data_for_step(self.steps.first)

                initial_data = {
                    'date': self.post_data['0']['date'],
                    'text': self.post_data['0']['text'],
                    'document_number': self.post_data['0']['document_number']
                }

                balance =  debit - credit
                if balance > 0:
                    initial_data.update({'credit': balance})
                else:
                    initial_data.update({'debit': -balance})

                # Add to initial_dict
                #self.initial_dict.update({next_step: initial_data})

                if len(self.form_list) <= int(self.steps.current) + 1:
                    self.form_list.update({next_step: TransactionCreateForm})

                new_form = TransactionCreateForm(next_step,
                    data=self.storage.get_step_data(next_step),
                    files=self.storage.get_step_files(next_step),
                    initial=initial_data)
                # change the stored current step
                self.storage.current_step = next_step
                return self.render(new_form, **kwargs)
            else:
                # no more steps, render done view
                return self.render_done(form, **kwargs)
        return self.render(form)

在我提交第一个表单后,我收到以下错误:

init()为参数'data'获取了多个值

我该如何解决这个问题?

编辑:嗨,这是堆栈跟踪

Traceback(最近一次调用最后一次):文件“/home/$$/.virtualenvs/pyVerein/lib/python3.6/site-packages/django/core/handlers/exception.py”,第41行,内部响应= get_response(request)文件“/home/$$/.virtualenvs/pyVerein/lib/python3.6/site- packages / django / core / handlers / base.py”,第187行,在_get_response response = self.process_exception_by_middleware(e ,请求)文件“/home/$$/.virtualenvs/pyVerein/lib/python3.6/site-packages/django/core/handlers/base.py”,第185行,在_get_response response = wrapped_callback(request,* callback_args) ,** callback_kwargs)文件“/home/$$/.virtualenvs/pyVerein/lib/python3.6/site-packages/django/views/generic/base.py”,第68行,在视图中返回self.dispatch(请求,* args,** kwargs)文件“/home/$$/.virtualenvs/pyVerein/lib/python3.6/site-packages/formtools/wizard/views.py”,第248行,在调度响应=超级(WizardView) ,self).dispatch(request,* args,** kwargs)File“/home/$$/.virtualenvs/pyVerein/lib/python3.6/site-packages/django/views/generic/b ase.py“,第88行,在调度返回处理程序(request,* args,** kwargs)文件”/home/$$/Entwicklung/pyVerein/pyVerein/finance/views.py“,第669行,在post initial = initial_data)TypeError:init()获得参数'data'的多个值

代码可在此处获取:https://github.com/HamburgerJungeJr/pyVerein/tree/accounting