Django如何将主键值存入关联外键字段?附相关代码示例
解决方案
你要实现的需求有两种可行方案,优先推荐第一种,不需要额外修改HTML,安全性更高:
方案1:视图层直接赋值(推荐)
因为你的路由已经把task_id传到视图函数里了,直接在创建edit_page实例时赋值外键即可,不需要通过HTML传值,避免被恶意篡改。
修正后的视图代码:
from django.shortcuts import get_object_or_404 # 新增导入,避免查不到数据时报500 def edit_task(request, task_id): # 先查对应的Tasklist实例,不管POST还是GET都要用 task = get_object_or_404(Tasklist, pk=task_id) if request.method == "POST": updatedate=request.POST.get("updatedate","") time_from=request.POST.get("time_from","") time_to=request.POST.get("time_to","") messagelogs=request.POST.get("messagelogs","") # 创建edit_page时传入old_id参数,赋值为上面查到的task实例 test_list=edit_page( old_id=task, # 外键直接传关联的模型实例即可 updatedate=updatedate, time_from=time_from, time_to=time_to, messagelogs=messagelogs ) test_list.save() form = TaskForm(request.POST or None, instance=task) if form.is_valid(): form.save() messages.success(request,"Task Edited ") return redirect('email_updatetask', task_id) # 你原来的第二个return永远不会执行,直接删掉即可 else: return render(request, 'edit.html', {'task_obj': task})
方案2:通过HTML表单隐藏字段传值
如果你确实需要通过HTML传递主键值,按下面的步骤修改:
第一步:修改edit.html表单代码
在你的form标签内部添加隐藏输入框:
<form method="POST"> {% csrf_token %} <!-- 新增隐藏字段,存储Tasklist的主键 --> <input type="hidden" name="task_id" value="{{ task_obj.id }}"> <!-- 你原来的其他表单字段,比如updatedate、time_from等正常写 --> <div> <label>更新日期:</label> <input type="date" name="updatedate" required> </div> <div> <label>开始时间:</label> <input type="time" name="time_from" required> </div> <div> <label>结束时间:</label> <input type="time" name="time_to" required> </div> <div> <label>修改日志:</label> <textarea name="messagelogs"></textarea> </div> <button type="submit">提交修改</button> </form>
第二步:视图层取值赋值
def edit_task(request, task_id): if request.method == "POST": # 从POST请求里拿隐藏字段传的task_id task_pk = request.POST.get("task_id") task = get_object_or_404(Tasklist, pk=task_pk) updatedate=request.POST.get("updatedate","") time_from=request.POST.get("time_from","") time_to=request.POST.get("time_to","") messagelogs=request.POST.get("messagelogs","") test_list=edit_page( old_id=task, updatedate=updatedate, time_from=time_from, time_to=time_to, messagelogs=messagelogs ) test_list.save() # 后续逻辑不变 form = TaskForm(request.POST or None, instance=task) if form.is_valid(): form.save() messages.success(request,"Task Edited ") return redirect('email_updatetask', task_id) else: task_obj = get_object_or_404(Tasklist, pk=task_id) return render(request, 'edit.html', {'task_obj': task_obj})
注意事项
- 外键字段赋值时可以直接传关联模型的实例,也可以传
old_id_id=task_id直接存主键值,两种写法都有效 - 建议优先用方案1,隐藏字段传值可以被用户篡改,存在数据安全风险
- 原视图中两个连续的return,第二个永远不会执行,建议直接删除冗余代码
内容的提问来源于stack exchange,提问作者Surya AB
相关产品推荐
相关产品推荐

