簡體   English   中英

Django-為同一字段提交具有多個輸入的表單

[英]Django - Submitting form with multiple inputs for same field

預警:我對Django(和Web開發,一般而言)很陌生。

我正在使用Django托管基於Web的UI,該UI將從簡短的調查中獲取用戶輸入,並通過我在Python中開發的一些分析將其輸入,然后在UI中呈現這些分析的可視化輸出。

我的調查包含10個問題,詢問用戶他們對某個特定主題的認同程度。

用於調查的UI示例:

UI輸入畫面示例

對於models.py ,我有2個字段:問題與選擇

class Question(models.Model):
    question_text = models.CharField(max_length=200)

    def __str__(self):
        return self.question_text

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text

我想讓用戶選擇他們對所有10個問題的回答,然后單擊“提交”立即提交所有回答,但是我在Django中如何處理該問題上遇到了麻煩。

這是我正在使用的html表單,但是此代碼段在每個問題后都放置了一個“提交”按鈕,並且一次只允許一次提交。

注意:以下代碼為每次迭代創建一個特定於問題的表格。

{% for question in latest_question_list %}
    <form action="{% url 'polls:vote' question.id %}" method="post">
    {% csrf_token %}
        <div class="row">
            <div class="col-topic">
                <label>{{ question.question_text }}</label>
            </div>
            {% for choice in question.choice_set.all %}
                <div class="col-select">
                    <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
                    <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
                </div>
            {% endfor %}
        </div>

    <input type="submit" value="Vote" />
    </form>
{% endfor %}

我對如何在一次提交中接受多個輸入(全部用於問題/選擇)並將其返回到views.py感興趣。

編輯:添加VIEWS.PY

目前,我的views.py腳本只處理一個問題/選擇對。 一旦弄清如何允許用戶一次提交所有10個問題/選擇的表單,我將需要在views.py中反映出來。 這可能是問題的第二部分。 首先,如何通過一個“提交”按鈕使用戶對所有10個問題提交所有答案? 其次,如何設置views.py一次接受多個值?

views.py

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/survey.html', {
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()

        return HttpResponseRedirect(reverse('polls:analysis'))

請讓我知道是否需要其他上下文。

提前致謝!

-C

您只需要稍微不同地組織模板,即可在同一form包含多個問題。 用HTML拼湊起來,它會轉換成多個文本輸入,然后在一個表單中轉換成下面的一個提交輸入:

<form action="{% url 'polls:vote' question.id %}" method="post">
    {% for question in latest_question_list %}
    {% csrf_token %}
        <div class="row">
            <div class="col-topic">
                <label>{{ question.question_text }}</label>
            </div>
            {% for choice in question.choice_set.all %}
                <div class="col-select">
                    <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
                    <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
                </div>
            {% endfor %}
        </div>
    {% endfor %}
    <input type="submit" value="Vote" />
</form>

現在工作了嗎?

在您的views.py中使用getlist()

if method=="POST":
    choices = request.POST.getlist('choice')

我覺得您應該將輸入單選框更改為復選框。 收音機不允許多項選擇,但Checkbox允許。 請參閱此處: https : //docs.djangoproject.com/en/dev/ref/request-response/#django.http.QueryDict.getlist

理想情況下,這應該使用Django Forms完成。 Django表單具有widgetsRadioSelect是其中之一。 您可以使用它來呈現表單並立即獲得每個問題的答案。 但這將需要您當前的處理方式進行很多更改。

因此,您可以做的是,單擊提交按鈕,收集所有問題/選擇對,並通過POST請求立即發送它們。

{% for question in latest_question_list %}
    <form>
        <div class="row">
            <div class="col-topic">
                <label>{{ question.question_text }}</label>
            </div>
            {% for choice in question.choice_set.all %}
                <div class="col-select">
                    <input type="radio" name="choice" value="{{ choice.id }}" />
                    <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
                </div>
            {% endfor %}
        </div>
    </form>
{% endfor %}
<input id="submit-btn" type="submit" value="Vote" />

<script>
    $(document).on('click', '#submit-btn', function(event){
        var response_data = []
        var question_objs = $('.col-topic');
        var choice_objs = $('.col-select');

        for(i=0;i<question_objs.length;i++){
            var question_text = $(question_objs[i]).find('label').text();
            var choice_id = $(choice_objs[i]).find('input').val();
            var choice_text = $(choice_objs[i]).find('label').text();
            var question_choice = {
                "question_text": question_text,
                "choice_id": choice_id,
                "choice_text": choice_text
            }
            response_data.push(question_choice);
        }
        $.ajax({
            type: "POST",
            url: "url_to_your_view",
            data: response_data,
            success: function(response){
                alert("Success");
            }
        });
    });
</script>

這就是您的視圖外觀。

def question_choice_view(request):
    if request.method == "POST":
        question_choice_data = request.POST['data']
        # further logic

現在,question_choice_data是詞典列表。 列表中的每個字典將具有用戶響應的question_text,choice_text和choice id。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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