[英]Data is shown before form submission in Django 4.1
社區!
我的目標是創建一個應用程序,它接受一些用戶輸入,進行機器學習並顯示結果。 我想知道每個預測的結果是否正確。 這就是我嘗試實施反饋系統的原因,用戶可以根據需要將答案標記為“正確”或“不正確”。
確切地說,我有兩個按鈕:“預測看起來像真的”和“預測不正確”。 單擊其中一個按鈕后,我會看到一個帶有 3 個復選框的彈出對話框,用戶可以在其中提供其他信息(這不是必需的)。
帶有這些復選框的forms.py
如下所示:
from django import forms
class checkboxForm(forms.Form):
is_winner_reason_true = forms.BooleanField(required=False, label="The first place in importance coincides with reality", label_suffix='')
is_top5_reason_true = forms.BooleanField(required=False, label="Top 5 includes friends with high importance", label_suffix='')
is_other_reason_true = forms.BooleanField(required=False, label="Other", label_suffix='')
class checkboxFormFalsePred(forms.Form):
is_winner_reason_false = forms.BooleanField(required=False, label="The other person should come first in importance", label_suffix='')
is_top5_reason_false = forms.BooleanField(required=False, label="Top 5 includes friends with low importance", label_suffix='')
is_other_reason_false = forms.BooleanField(required=False, label="Other", label_suffix='')
我想通過單擊兩個按鈕之一(值將是True
或False
)來獲取數據,然后,如果用戶決定提供額外的反饋,也可以從該反饋中獲取數據。
models.py
看起來像這樣:
from django.db import models
from allauth.socialaccount.models import SocialAccount
# Create your models here.
class ResultInfo(models.Model):
uid = models.ForeignKey(SocialAccount, on_delete=models.CASCADE)
friend_id = models.CharField(max_length = 16)
status = models.BooleanField() # whether the answer is True or False
status_description = models.CharField(max_length = 16, null=True, blank=True) # the additional info about the answer
result_info = models.JSONField()
請注意, status_description
旨在從 3 個復選框中獲取額外數據。 最初,它作為字典出現,看起來像{'is_winner_reason_true': False, 'is_top5_reason_true': False, 'is_other_reason_true': False}
。 稍后,我會將其轉換為一個類別,以便將其作為列status_description
存儲在數據庫中。
我創建了 AJAX 調用 forms 以防止在提交表單后刷新頁面。 它完成了它的工作,盡管有 2 秒的延遲。
這是我的 HTML:
...
<button class="looks-like-true" value="True" name="looks-like-true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>
<span class="looks-like-true-content">
Looks like true
</span>
</button>
<button class="false-prediction" value="False" name="false-prediction">
<span class="false-prediction-content">
Prediction is incorrect
</span>
</button>
<dialog class="verification-modal" id="verify-true">
<p>Thanks for the feedback! What do you like about the prediction? </p><p>(Answer is optional, but more information would help us improve the predictive model)</p>
<div class="modal-checkboxes">
<form action="" method="POST" id="form-verify-true">{% csrf_token %}
{{res_verif_form.as_p}}
<input type="submit" value="Send" class="show-more-close-button">
</form>
</div>
</dialog>
<dialog class="verification-modal" id="verify-false">
<p>Thanks for the feedback! What did not you like about the prediction? </p><p>(Answer is optional, but more information would help us improve the predictive model)</p>
<div class="modal-checkboxes">
<form action="" method="POST" id="form-verify-false">{% csrf_token %}
{{res_verif_form_false_pred.as_p}}
<input type="submit" value="Send" class="show-more-close-button">
</form>
</div>
</dialog>
...
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script>
const verifyModal = document.querySelector('#verify-true')
const verifyModalFalse = document.querySelector('#verify-false')
$(document).ready(
$('#form-verify-true').submit(function(e){
e.preventDefault();
var serializedData = $(this).serialize();
$.ajax({
type:"POST",
url: "./",
data: serializedData,
success: function(response){
$("#form-verify-true").trigger('reset');
verifyModal.close();
}
});
})
);
$(document).ready(
$('#form-verify-false').submit(function(e){
e.preventDefault();
var serializedData = $(this).serialize();
$.ajax({
type:"POST",
url: "./",
data: serializedData,
success: function(response){
$("#form-verify-false").trigger('reset');
verifyModalFalse.close();
}
});
})
);
$(document).ready(
$('.looks-like-true').click(function(){
$.ajax({
type:"POST",
url: "./",
data: {'content_id': $(this).attr('name'),'operation':'ans_submit','csrfmiddlewaretoken': '{{ csrf_token }}'},
success: function(response){
console.log("Success")
}
});
})
);
$(document).ready(
$('.false-prediction').click(function(){
$.ajax({
type:"POST",
url: "./",
data: {'content_id': $(this).attr('name'),'operation':'ans_submit','csrfmiddlewaretoken': '{{ csrf_token }}'},
success: function(response){
console.log("Success")
}
});
})
);
</script>
來自views.py
的一段代碼:
if (request.method == 'POST') and (request.POST.get('content_id', None) == "looks-like-true"):
res_verif_form = checkboxForm(request.POST)
if (res_verif_form.is_valid()):
print(res_verif_form.cleaned_data)
return HttpResponse('success')
if (request.method == 'POST') and (request.POST.get('content_id', None) == "false-prediction"):
res_verif_form_false_pred = checkboxFormFalsePred(request.POST)
if (res_verif_form_false_pred.is_valid()):
print(res_verif_form_false_pred.cleaned_data)
res_verif_form = checkboxForm()
res_verif_form_false_pred = checkboxFormFalsePred()
現在,問題來了。
單擊兩個按鈕之一后,附加問題的數據將被打印出來,但在提交包含這些附加問題的表單之前。 此外,在我提交表格后,我根本沒有得到打印信息。 只需在我的 cmd 中"POST /id4564365/results/ HTTP/1.1" 200 86111
86111。
我試圖刪除這些行:
$(document).ready(
$('.looks-like-true').click(function(){
$.ajax({
type:"POST",
url: "./",
data: {'content_id': $(this).attr('name'),'operation':'ans_submit','csrfmiddlewaretoken': '{{ csrf_token }}'},
success: function(response){
console.log("Success")
}
});
})
);
$(document).ready(
$('.false-prediction').click(function(){
$.ajax({
type:"POST",
url: "./",
data: {'content_id': $(this).attr('name'),'operation':'ans_submit','csrfmiddlewaretoken': '{{ csrf_token }}'},
success: function(response){
console.log("Success")
}
});
})
);
然后我將views.py
更改為如下所示:
if (request.method == 'POST'):
res_verif_form = checkboxForm(request.POST)
if (res_verif_form.is_valid()):
print(res_verif_form.cleaned_data)
return HttpResponse('success')
if (request.method == 'POST'):
res_verif_form_false_pred = checkboxFormFalsePred(request.POST)
if (res_verif_form_false_pred.is_valid()):
print(res_verif_form_false_pred.cleaned_data)
好吧,它奏效了。 我的數據現在在提交表單后打印。 但問題是我沒有從前兩個按鈕獲取數據。
有幾種方法可以解決這個問題。 我要給你的解決方案涉及 AJAX,盡管它不一定是你想要的。 原因是因為它是您要嘗試使用的,並且更容易獲得所需的 output。
我將從看起來多余的forms.py
開始。 reason
是一個基於按鈕提供的用戶輸入的變量,因為可以訪問該變量並且可以使用 JavaScript 處理標簽,因此不需要兩個 forms:
class checkBoxForm(forms.Form):
is_winner = forms.BooleanField(
required=False,
label="The first place in importance coincides with reality",
label_suffix=''
)
is_top5 = forms.BooleanField(
required=False,
label="Top 5 includes friends with high importance",
label_suffix=''
)
is_other = forms.BooleanField(
required=False,
label="Other",
label_suffix=''
)
即使在template.html
中進行了一些更改,我也嘗試盡可能多地保留原始代碼(盡管老實說我會更改一些名稱)。
在接下來的 HTML 部分中, checkBoxForm
用於像您最初所做的那樣輕松呈現模態輸入,但請注意尚未提交表單:
<button class="looks-like-true" name="looks-like-true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M470.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L192 338.7 425.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>
<span class="looks-like-true-content">
Looks like true
</span>
</button>
<button class="false-prediction" name="false-prediction">
<span class="false-prediction-content">
Prediction is incorrect
</span>
</button>
<dialog class="verification-modal">
<p>Thanks for the feedback! What do you like about the prediction? </p><p>(Answer is optional, but more information would help us improve the predictive model)</p>
<div class="modal-checkboxes">
{{form.as_p}}
<button id="send-form" >Send</button>
</div>
</dialog>
相反,通過 JavaScript (jQuery) 收集數據並使用 AJAX 發送它來提交表單。通過遵循有關如何使用 AJAX 的 CSRF 保護的文檔獲取csrftoken
,並根據請求正確設置它header
:
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script>
const verifyModal = document.querySelector('.verification-modal');
let reason = null;
function getCookie(name) {
...
}
$('.looks-like-true').click(function() {
reason = true;
$("label[for='id_is_winner']").text("The first place in importance coincides with reality");
$("label[for='id_is_top5']").text("Top 5 includes friends with high importance");
verifyModal.showModal();
});
$('.false-prediction').click(function() {
reason = false;
$("label[for='id_is_winner']").text("The other person should come first in importance");
$("label[for='id_is_top5']").text("Top 5 includes friends with low importance");
verifyModal.showModal();
});
$('#send-form').click(function() {
is_winner = document.querySelector('#id_is_winner').checked;
is_top5 = document.querySelector('#id_is_top5').checked;
is_other = document.querySelector('#id_is_other').checked;
url = '/your/url/'
const csrftoken = getCookie('csrftoken');
headers = {'X-CSRFToken': csrftoken, 'Content-Type': 'application/json'}
data = {
'reason': reason,
'is_winner': is_winner,
'is_top5': is_top5,
'is_other': is_other,
}
$.ajax({
type:"POST",
url: url,
headers: headers,
data: JSON.stringify(data),
success: function(response){
console.log(response.msg);
verifyModal.close();
// reload or redirect or update page using JS...
location.reload();
// window.location.replace("https://stackoverflow.com/a/506004/7100120");
}
});
});
</script>
視圖.py
from .forms import checkBoxForm
from django.http import JsonResponse
import json
def your_view_name(request):
if request.method == 'POST':
data = json.loads(request.body)
reason = data.pop('reason')
print(f'Reason: {reason}')
print(f'Status Description: {data}')
# Output Sample
# Reason: True
# Status Description: {'is_winner': True, 'is_top5': False, 'is_other': True}
return JsonResponse({'msg': 'success'})
form = checkBoxForm()
context = {
'form': form,
}
return render(request, 'your_template.html', context)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.