1

我正在开发一个 django web 应用程序,并且有一个 html 表单,提交表单时我需要做两件事:在应用程序的数据库中创建一条记录并将收集到的一些值发布到另一个网站(例如支付网站)。

我遇到的问题是让表单同时做两件事。我知道 HTML 表单只能有一个操作,并且我在 StackOverflow 上阅读了一些关于使用 javascript 让表单执行 2 个或更多操作的帖子,但是到目前为止我尝试的所有方法都不适用于这种情况. 他们似乎都只能采取一种行动。

这就是我的 django 模板现在的样子:

{% extends "some other template" %}
{% block content %}
<div>
...
<form id=form1" name="trans_form" method="POST" >
...
<!--DATA TO POST TO PAYMENT SITE-->
<input type="hidden" name="transaction_id" value="some value" />
<input type="hidden" name="transaction_amount" value="some value"/>
<input type="hidden" name="customer_id" value="some value" />
<input type="hidden" name="customer_name" value="some value" />
<!--DATA TO POST TO PAYMENT SITE-->
...
<!--DATA TO POST TO APP DATABASE-->
<input type="hidden" name="user" value="{{ user.id }}">
<input type="hidden" name="type" value="CC">
<input type="hidden" name="ref_no" value="{{ ref_no }}">
Amount: <input type="text" name="amount" id="id_amount" required />
Ref ##: <span>{{ ref_no }}</span>
Date: <span>{{ cur_date|date:'d/m/Y' }}</span>
<a href="#" id="pay-btn" class="button" onclick="submitForm();">Submit</a>
<!--DATA TO POST TO APP DATABASE-->
...
</form>
...
</div>
{% endblock %}

{% block script %}
<script>
function submitForm()
{
    createRecord(document.forms["trans_form"]);
    sendToPay(document.forms["trans_form"]);
}
function sendToPay(f)
{
    f.action= "www.paymentsite.com";
    f.target = null;
    f.onsubmit = null;
    f.submit();
}
function createRecord(f)
{
    f.action = "url to view that creates the record in database";
    f.target = "_blank";
    f.onsubmit = null;
    f.submit();
}
</script>
{% endblock %}

你怎么看?我在努力实现不可能吗?如果没有,请指出我正确的方向。谢谢。

4

2 回答 2

6

为什么不简单地从您的控制器 POST 到支付站点:

def handle_payment(request):
    post_to_payment_site(request)
    write_payment_info_to_db(request)

def post_to_payment_site(request):
    data = {'transaction_id': request.form['transaction_id',
        # etc.
    }

    requests.post('payment-provider-url', data=data)

如果您不能接受针对您的支付提供商的 POST 数据,那么您可以执行以下操作之一:

  • 向您的支付提供商发送 XHR 请求 - 这要求您的支付提供商为您发布到的端点正确实施 CORS。该请求完成后,您可以正常提交表单。
  • 将表单的属性更改target为指向一个iframe或新的选项卡/窗口。然后,当iframe加载时,删除target属性,切换action回您的端点并提交。
于 2013-07-26T16:01:16.140 回答
0

我终于解决了我的问题。我不确定它是否是最有效的解决方案,但就是这样。

我又制作了一个 HTML 页面来充当我的应用程序和支付网站之间的中间人。这是一个非常简单的页面,实际上是第一个表单页面的复制品,但只有必填字段要发布到支付网站。这样,就不需要太多的 JavaScript。提交表单会在应用程序数据库中创建一条记录,将所需数据发送给“中间人”,然后中间人将数据发布到支付网站。用户在整个过程中从未真正看到过中间人。

就像我说的,这可能不是最有效的解决方案,但效果很好。

首先,这里是views.py的代码:

def write_payment_info_to_db(request):
dt = datetime.now()
form = Form()
err = False
if request.method == 'POST':
    #Collect data to send to GTPay
    transaction_id      = request.POST['transaction_id']
    transaction_amount  = request.POST['transaction_amount']
    customer_id         = request.POST['customer_id']
    customer_name       = request.POST['customer_name']
    #Create record in db for "valid" form data
    form = Form(request.POST)
    if form.is_valid():
        form.save()
        return render_to_response('middleman.html', {'transaction_id': transaction_id,
                                                    'transaction_amount': transaction_amount,
                                                    'customer_id': customer_id,
                                                    'customer_name': customer_name},
                                    context_instance=RequestContext(request))
    else:
        err = form.errors
        return ...
else:
    return ...

这是中间人:

<html>
<body onload="document.submit2paymentsite_form.submit()">
    <form name="submit2paymentsite_form" action="payment-provider-url" target="_self" method="POST">
        {% csrf_token %}
        <input type="hidden" name="transaction_id" value="{{ transaction_id }}" />
        <input type="hidden" name="transaction_amount" value="{{ transaction_amount }}" />
        <input type="hidden" name="customer_id" value="{{ customer_id }}" />
        <input type="hidden" name="customer_name" value="{{ customer_name }}" />
    </form>
</body>

于 2013-07-29T13:39:14.287 回答