我最近完成了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 %}
我怀疑我的投票()功能写得不好,但我不知道如何修复它。欢迎任何提示或替代方案,谢谢。
答案 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])
它工作了!!!