如何/在何处停止Django Formwizards的"完成"方法在付款失败时被调用

sha*_*awn 5 django validation call formwizard

我查看了django文档,做了大量的谷歌搜索,并尝试了不少解决方案但无济于事.

我使用Django的FormWizard创建了一个3部分表单.一旦验证了最后一个表格(付款表格),我就会向付款网关发送付款请求.

我正在使用FormWizard的'process_step'方法进行付款处理.

我很难弄清楚如何在付款失败时让FormWizard再次显示付款页面.就像现在一样,FormWizard的'done'方法被调用(在我在process_step中完成处理之后),因为所有表单都已经过验证.

我想知道是否需要覆盖调用方法.不确定如何做到这一点,但我现在正试图解决这个问题.

任何帮助将非常感激.问候,肖恩

class TrainingWizard(FormWizard):

def process_step(self,request,form,step):
    if step == 0:
        self.extra_context = {'stepOne': "One"}
    if step == 1:
        self.extra_context = {'stepTwo': "Two"}
    if step == 2:
        if self.get_response != "Success":
            #Payment Failed
            #Add error message
            #Show Payment Form Again to allow user to retry     
    return

def get_response(self):
    #return "Success"
    return "Declined"

def done(self, request, form_list):
    return HttpResponseRedirect('/training-registration-complete/')
Run Code Online (Sandbox Code Playgroud)

Aar*_*uyn 6

我终于找到了解决方案.我在Django 1.4中使用SessionWizardView类.

我重写了render_done()函数(直接从django/django/contrib/formtools/wizard/views.py复制它并调整它.

在'final_form_list.append(form_obj)'和最后三行之间(以'done_response = self.done(final_form_list,**kwargs)'开头)我处理与支付网关的谈话.

如果出现错误,我会重定向回到表单中的最后一步(使用self.render.revalidation_failure()),他们可以再试一次.

这是一段代码:

try:
    charge = stripe.Charge.create(
        amount=price_in_cents,
        currency="usd",
        card=token,
        description="BlahStore Order Number: %s" %(self.order.pk),
    )
except (stripe.APIConnectionError, stripe.APIError, stripe.AuthenticationError, stripe.CardError, stripe.InvalidRequestError, stripe.StripeError) as e:
    from django.forms import forms
    from django.forms.util import ErrorList
    errors = final_form_list[3]._errors.setdefault(forms.NON_FIELD_ERRORS, ErrorList())
    errors.append(e.message)
    return self.render_revalidation_failure(3, final_form_list[3], **kwargs)
Run Code Online (Sandbox Code Playgroud)

您会注意到我在几个地方进行了"3"硬编码 - 这是因为我的向导有四个步骤且数组基于零.我将错误消息设置为显示然后重定向.如果你想坚持使用process_step(),我相信这很容易适应这个,但我个人认为TheRightWay是要覆盖render_done()函数.