Django - 提交具有相同字段的多个输入的表单

时间:2017-11-24 08:21:22

标签: python html django forms

预警:我对Django(以及一般的Web开发)都很陌生。

我正在使用Django来托管一个基于Web的UI,该UI将从一个简短的调查中获取用户输入,通过我在Python中开发的一些分析提供它,然后在UI中呈现这些分析的可视输出

我的调查包含10个问题,询问用户他们对特定主题的认同程度。

调查用户界面的示例:

Example of UI input screen

对于 models.py ,我有两个字段:问题&选择

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

感兴趣

编辑:添加视图.PY

目前,我的 views.py 脚本处理单个问题/选择对。一旦我弄清楚如何允许用户一次性提交所有10个问题/选项,我需要在 views.py 中反映出来。这可能是问题的第2部分。首先,如何让用户通过一个“提交”按钮将所有回复提交到所有10个问题?其次,如何设置 views.py 一次接受多于1个值?

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

2 个答案:

答案 0 :(得分:0)

您只需稍微改变一下您的模板,就可以在同一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>

现在有效吗?

答案 1 :(得分:0)

理想情况下,这应该是使用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和用户响应的选择ID。