簡體   English   中英

Django 4.1 表單提交前顯示數據

[英]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='')

我想通過單擊兩個按鈕之一(值將是TrueFalse )來獲取數據,然后,如果用戶決定提供額外的反饋,也可以從該反饋中獲取數據。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM