Django - 在同一页面/表单中对多个类别进行投票

时间:2017-11-19 18:44:57

标签: python django

我最近完成了Django入门教程,我想创建一个民意调查应用程序,可以在同一页面/表单上对多个类别进行投票。一切正常,但是当我点击'投票' (即选择选项并提交表单)以下错误一直显示:

TypeError at /polls/results/

int() argument must be a string or a number, not 'QueryDict'

我的 models.py:

中的代码
class Caty(models.Model):
    category_name = models.CharField(max_length=250)

class Choice(models.Model):
    category = models.ForeignKey(Caty, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=250)
    votes = models.IntegerField(default=0)

来自我的 views.py:

的代码
from django.shortcuts import get_list_or_404, render
from django.http import HttpResponse
from models import Caty, Choice

def index(request):
    caty_list = Caty.objects.all()
    context = {'caty_list': caty_list} 
    return render(request, 'polls/index.html', context)

def results(request):
    return render(request, 'polls/results.html')

def vote(request):
    caty = get_list_or_404(Caty)
    for cat in caty:
        selected_choice = cat.choice_set.get(pk=request.GET)
        selected_choice.votes += 1
        selected_choice.save()
    return HttpResponse('polls:results')

我在the tutorial get_list_or_404()交换了 get_object_or_404(),因为我期待对多个问题进行投票

来自 index.html

代码:

{% if caty_list %}
    <form action="{% url 'polls:vote' %}" method="post">
    {% for caty in caty_list %}
        {% csrf_token %}
        {{ caty }} <br />
        <fieldset>
        {% for choice in caty.choice_set.all %}
            <input type="radio" name="{{ caty }}" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
            <label for="choice{{ forloop.counter }}">{{ choice }}</label><br />
        {% endfor %}
        </fieldset>
    {% endfor %}
    <input type="submit" value="Vote" />
    </form>
{% else %}
    <p>No Categories available.</p>
{% endif %}

我怀疑我的投票()功能写得不好,但我不知道如何修复它。欢迎任何提示或替代方案,谢谢。

2 个答案:

答案 0 :(得分:1)

vote方法中,您应该传递包含GET的特定pk参数(使用getlist方法,因为您需要一个选项列表):

def vote(request):
    caty = get_list_or_404(Caty)
    for cat in caty:
        # Get the list of ids from the list of radio buttons
        selected_choices_pks = request.GET.getlist(caty.category_name)

        # Filter the Choices objects using theses ids
        selected_choices = Choice.objects.filter(pk__in=selected_choices_pks)

        # Increment all the filtered choices votes by 1 using the F() expression
        selected_choices.update(votes=F('votes') + 1)

return HttpResponse('polls:results')

另外,对于你将选票增加1的方法,我认为你应该使用F()表达式和update方法。 它将允许您避免多个查询(加载每个对象,保存每个对象等)。

答案 1 :(得分:1)

<强>更新

我换了:

selected_choice = cat.choice_set.get(pk=request.GET)

在我的投票()功能中:

selected_choice = cat.choice_set.get(pk=request.POST[cat.category_name])

它工作了!!!