我的模板中有以下代码:
<form action="" method="post">{% csrf_token %}
{%for category, category_votes in votes%}
<p>{{category}}: {{category_votes}} <!-- displays as expected -->
<input type="hidden" name="votedCat" value="{{category}}" id={{forloop.counter}}>
<input type="submit" name="upvote" value="Vote for...">
<input type="submit" name="downvote" value="Vote against...">
</p>
{%endfor%}
</form>
变量{{category}}
在呈现时会按预期显示,但查看POST数据,"votedCat"
始终是category
中的最后votes
值。
例如,如果votes=[('a',1),('b',2),('c',3)]
,则request.POST['votedCat']
会返回'c'
,无论使用哪个输入按钮提交表单。我做错了什么?
答案 0 :(得分:3)
因为您只有一个表格,votedCat
有多个输入。点击任意按钮会提交整个表单, all votedCat
的值。如果您要访问request.POST.getlist('votedCat')
,您会看到实际上拥有所有值。
有两种方法可以解决这个问题。第一种是通过循环为每次迭代分别创建表单元素 - 为此,只需在循环内移动<form>
和</form>
元素。
第二个是让votedCat
输入实际上是提交按钮:
<input type="submit" name="votedCat" value="Vote for {{category}}" id={{forloop.counter}}>
这里的缺点是,现在你的变量中有'投票'字样,你需要在视图代码中解析它。
比这两者更好的是设置简单的单选按钮或选择具有单个提交按钮的框,但我知道设计要求有时会妨碍。
最后,您应该使用Django的表单框架,而不是使用手动HTML并直接处理POST。
答案 1 :(得分:1)
我不确定这是否是最佳解决方案,但您可以在循环中创建新的form
:
{%for category, category_votes in votes%}
<p>{{category}}: {{category_votes}} <!-- displays as expected -->
<form action="" method="post">{% csrf_token %}
<input type="hidden" name="votedCat" value="{{category}}" id={{forloop.counter}}>
<input type="submit" name="upvote" value="Vote for...">
<input type="submit" name="downvote" value="Vote against...">
</form>
</p>
{%endfor%}
您可以考虑使用django.forms.Form
类来构建和处理表单。