制作django html表单对提交执行2个操作

时间:2013-07-26 15:59:34

标签: javascript python html django

我正在开发一个django网络应用程序,并且有一个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 %}
你怎么看?我想要实现不可能吗?如果没有,请指出正确的方向。感谢。

2 个答案:

答案 0 :(得分:6)

为什么不直接从控制器发送到付款网站:

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切换回您的终端并提交。

答案 1 :(得分: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>