Django如何通过子实例获取父模型属性并正确存储外键字段值
你遇到的问题本质是Django外键字段需要存储关联模型的实例/主键值,不能直接存储字符串格式的名称。而且你的设计可以更简化,不需要同时传作业名称和教师名称,只要传递作业ID就能一次性拿到两个关联数据,还能避免重名导致的数据错误。
第一步:优化模板表单的隐藏字段
把原来传作业名、教师名的隐藏字段,改成传作业的主键ID,代码如下:
<form enctype="multipart/form-data" action="{% url 'assignment' %}" method="POST"> {% csrf_token %} <!-- 替换成传递作业主键ID,无需额外传名称和教师字段 --> <input type="hidden" name="assignment_id" value="{{assignment.id}}"> <input required type="file" name="inputFile" placeholder="upload"> <button>Upload</button> </form>
这里直接传递作业ID的原因是:Assignment模型本身已经关联了创建教师,只要拿到作业实例就能直接获取对应的教师数据,不需要额外传参,也能避免前端恶意篡改教师参数的问题。
第二步:修改视图层的存储逻辑
先根据前端传的作业ID查询到作业实例,再从作业实例中提取创建教师的实例,直接传入Submissions的创建方法即可:
uploaded_file = request.FILES['inputFile'] # 拿到前端传递的作业ID assignment_id = request.POST.get('assignment_id') # 查询对应的作业实例 assignment_obj = Assignment.objects.get(id=assignment_id) student = Student.objects.get(student_username=request.user) document = Submissions.objects.create( submitted_by=student, submission_file=uploaded_file, submission_status=True, # 直接传入作业实例给外键字段 submission_title=assignment_obj, # 从作业实例中取关联的教师实例,传入对应外键字段 submitted_to=assignment_obj.assignment_creator )
可选兼容方案(不推荐,易出现重名匹配错误)
如果确实有需求要通过名称查询对应实例,可以用以下方式实现:
# 按作业名称查询作业实例 assignment_obj = Assignment.objects.get(assignment_title=ass_name) # 按教师用户名查询教师实例(需要和你Teacher模型的__str__返回值匹配) teacher_obj = Teacher.objects.get(teacher_username__username=teacher_name)
建议增加异常捕获逻辑,避免实例不存在时触发500错误。
内容的提问来源于stack exchange,提问作者F Nasir
相关产品推荐
相关产品推荐

