从HTML表单向Django数据库提交数据遇ValueError:如何关联外键选项?
问题解决:Django外键提交报错 ValueError
错误根源
你碰到的ValueError,是因为PersonInfo.gender是关联Gender模型的外键字段,必须传入Gender模型的实例,但你现在从POST请求里拿到的是字符串(比如"Female"),直接赋值自然会报错。另外你的HTML下拉列表循环的是all_record(也就是已有的员工记录),这会重复显示已有员工的性别,而非所有可选的Gender选项。
修复步骤
1. 修正HTML下拉列表
把循环对象改成Gender模型的所有实例,同时给选项设置value为Gender的ID,这样提交时传递的是ID而非字符串:
<select name="gender" class="form-select"> <option selected>选择性别</option> {% for gender in gender_options %} <option value="{{ gender.id }}">{{ gender.gender }}</option> {% endfor %} </select>
2. 修改视图函数
- GET请求时,把所有Gender选项传给模板
- POST请求时,通过提交的ID获取对应的Gender实例,再赋值给PersonInfo:
def add_emp(request): if request.user.is_authenticated: all_record = PersonInfo.objects.all() # 将所有性别选项传递给模板 gender_options = Gender.objects.all() if request.method == "POST": pid = request.POST['pid'] first_name = request.POST['first_name'] middle_name = request.POST['middle_name'] last_name = request.POST['last_name'] birth_date = request.POST['birth_date'] # 获取选中的性别ID,再拿到对应的Gender实例 gender_id = request.POST['gender'] gender_instance = Gender.objects.get(id=gender_id) new_employee = PersonInfo( pid=pid, first_name=first_name, middle_name=middle_name, last_name=last_name, birth_date=birth_date, gender=gender_instance ) new_employee.save() messages.success(request, "员工添加成功") return render(request, 'add_emp.html', {'all_record': all_record, 'gender_options': gender_options}) else: return render(request, 'add_emp.html', {'all_record': all_record, 'gender_options': gender_options}) else: messages.success(request, "访问被拒绝") return redirect('lobby')
3. 可选优化:处理未选性别情况
如果用户未选择性别就提交,会因gender_id不存在报错,可以添加判断逻辑:
# 在POST处理部分修改 gender_id = request.POST.get('gender') gender_instance = Gender.objects.get(id=gender_id) if gender_id else None
内容的提问来源于stack exchange,提问作者Josi
相关产品推荐
相关产品推荐

