我查看了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/')
答案 0 :(得分: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)
你会注意到我在几个地方有'3'硬编码 - 这是因为我的向导有四个步骤而且数组基于零。我将错误消息设置为显示然后重定向。如果你想坚持使用process_step(),我相信这很容易适应这个,但我个人认为TheRightWay是要覆盖render_done()函数。
答案 1 :(得分:0)
FormWizard知道字段验证,但除此之外的任何事情,例如信用卡处理都取决于您(或其他地方)的捕获和响应。
由于表单已经过验证,并且您现在有一个用户输入的POST,视图中的每个异常/结果都可以呈现给页面(带有RequestContext),并且还会向您添加错误消息。同样适用于forms.py。