Django Forms:如何在不修改URL的情况下避免使用隐藏输入
解决Django投票表单关联Question实例的问题(无需隐藏字段或修改URL)
我懂你的需求:循环渲染多个Question的投票表单,不想用隐藏输入存question_id,也不想改动现有URL结构,对吧?这里有个简单可行的方案,利用提交按钮的name属性来传递对应的Question ID,完全贴合你的要求。
步骤1:修改模板中的表单按钮
在循环里,给每个表单的提交按钮设置一个包含当前Question ID的name属性,保留投票类型的表单字段即可:
{% for question in list_passed_with_questions %} <p>{{ question.statement }}</p> <form method="post"> {% csrf_token %} {{ vote_form.as_p }} <!-- 按钮name包含question ID,提交时会把这个键值对发送到后端 --> <button type="submit" name="vote_for_{{ question.id }}">提交投票</button> </form> {% endfor %}
步骤2:在视图中解析Question ID并处理投票
后端视图里,你可以遍历POST请求的键,找到以vote_for_开头的键,拆分出对应的Question ID,再结合投票类型完成逻辑:
from django.shortcuts import get_object_or_404, redirect from .models import Question from .forms import VoteForm def vote_handler(request): if request.method == 'POST': # 提取Question ID question_id = None for post_key in request.POST: if post_key.startswith('vote_for_'): question_id = post_key.split('_')[-1] break if question_id: # 获取对应的Question实例 question = get_object_or_404(Question, id=question_id) # 处理投票表单 form = VoteForm(request.POST) if form.is_valid(): vote_type = form.cleaned_data['vote_type'] # 假设你的表单字段叫vote_type,值是'up'/'down' # 更新票数 if vote_type == 'up': question.up_votes += 1 elif vote_type == 'down': question.down_votes += 1 question.save() # 投票完成后重定向回原页面(避免重复提交) return redirect(request.META.get('HTTP_REFERER', '/')) # GET请求的处理(如果需要) return redirect('/')
方案优势
- 无隐藏字段:所有关联信息通过提交按钮的
name传递,不会在页面HTML里暴露额外的隐藏输入。 - 无需修改URL:所有表单都提交到同一个URL,完全保持原有URL结构。
- 逻辑清晰:后端通过键前缀快速定位对应的Question,处理逻辑简单直接。
如果你的vote_form字段名不是vote_type,只需要把代码里的对应部分改成你实际的字段名即可。另外,记得做好表单验证,确保投票类型是合法的值哦。
内容的提问来源于stack exchange,提问作者William Karlsson
相关产品推荐
相关产品推荐

