2013-07-26 54 views
1

我正在處理一個django網絡應用程序,並且有一個html表單,當表單提交時我需要做兩件事情:在應用程序數據庫中創建一個記錄併發布一些收集到另一個網站(例如支付網站)的價值。製作django html表單在提交時執行2個操作

我遇到的問題是讓窗體同時做兩件事。我知道一個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 %} 

你覺得呢?我是否想要實現不可能的目標?如果不是,請指出我的方向。謝謝。

+0

'f.action ='也許應該包括'的https:/ /'在你的'sendToPay'函數的'www'之前。 –

回答

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切換回您的端點並提交。
+0

感謝您的建議。我能夠配置write_payment_info_to_db函數,並且工作正常。但是,按照您的建議設置post_to_payment_site函數會導致類型錯誤「QueryDict對象不可調用」。我在最後一行使用了「request.POST('payment-provider-url',data = data)」,這是錯誤的例外位置。 – debodunmcg

+0

@debodunmcg - 這是'請求',而不是'請求';-)我假設你有權訪問[第三方請求庫](docs.python-requests.org)。你也可以使用'urllib',它只需要幾行代碼。對不起,我應該說清楚了! –

+0

沒問題,@Sean。我無法訪問付款網站的請求庫,但我有一個可行的解決方案。我製作了一個HTML頁面,它像我的表單和付款網站之間的中間人一樣。因此,在提交表單時,記錄會在我的應用程序數據庫中創建,付款網站所需的相關數據將發送到中間人HTML頁面,並在加載時將數據提交給付款網站。這樣的美妙之處在於用戶永遠不會看到中間人。可能不是最好的解決方案,因爲它需要一個額外的跳躍,但它的工作原理。 :-) – debodunmcg

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> 

相關問題