在Django请求处理中,调用存储过程的实例应放于何处?
存储过程修改数据时,Tarea实例的正确放置位置
我正在使用存储过程修改数据表,已经创建了一个Tarea实例,需要在请求处理函数中调用它,请问这个实例应该放在代码的哪个位置?
用户提供的现有代码:
def modificartarea(request, id): tarea = get_object_or_404(Tarea, id=id) data = { 'tarea': CrearTareaForm(instance=tarea) } if request.method=="POST": if request.POST.get('nombre') and request.POST.get('descripcion') and request.POST.get('inicio') and request.POST.get('termino') and request.POST.get('repetible') and request.POST.get('activo') and request.POST.get('estado') and request.POST.get('creador') and request.POST.get('tarea_anterior'): tareaupdate= Tarea() tareaupdate.nombre=request.POST.get('nombre') tareaupdate.descripcion=request.POST.get('descripcion') tareaupdate.inicio=request.POST.get('inicio') tareaupdate.termino=request.POST.get('termino') tareaupdate.repetible=request.POST.get('repetible') tareaupdate.activo=request.POST.get('activo') tareaupdate.estado=EstadoTarea.objects.get(pk=(request.POST.get('estado'))) tareaupdate.creador=Empleado.objects.get(rut=(request.POST.get('creador'))) tareaupdate.tarea_anterior=Tarea(pk=(request.POST.get('tarea_anterior'))) cursor=connection.cursor() cursor.execute("call SP_modificar_tarea('"+tareaupdate.nombre+"','"+tareaupdate.descripcion+"', '"+tareaupdate.inicio+"', '"+tareaupdate.termino+"', '"+tareaupdate.repetible+"', '"+tareaupdate.activo+"', '"+str(tareaupdate.estado.id)+"', '"+str(tareaupdate.creador.rut)+"', '"+str(tareaupdate.tarea_anterior.id)+"')") messages.success(request, "La tarea "+tareaupdate.nombre+" se edito correctamente ") return render(request, 'app/modificartarea.html', data) else: return render(request, 'app/modificartarea.html', data)
解决方案:复用已获取的Tarea实例,无需新建
你完全不需要创建新的Tarea()实例,直接复用函数开头通过get_object_or_404获取的tarea对象即可,具体调整如下:
删除新建实例的代码
删掉tareaupdate= Tarea()这一行,所有字段赋值直接操作已有的tarea实例。调整字段赋值逻辑
把所有tareaupdate.xxx替换成tarea.xxx,比如:tarea.nombre = request.POST.get('nombre') tarea.descripcion = request.POST.get('descripcion') # ... 其余字段同理修复存储过程调用的关键问题
你的存储过程目前缺少要修改的任务ID参数,这会导致存储过程无法定位到要更新的记录,必须把函数接收的id传入存储过程的参数列表中,比如修改后的存储过程调用:cursor.execute(f"call SP_modificar_tarea('{id}', '{tarea.nombre}', '{tarea.descripcion}', '{tarea.inicio}', '{tarea.termino}', '{tarea.repetible}', '{tarea.activo}', '{str(tarea.estado.id)}', '{str(tarea.creador.rut)}', '{str(tarea.tarea_anterior.id)}')")(用f-string拼接字符串比直接
+拼接更安全易读,也能避免部分语法错误)调整成功提示信息
把提示里的tareaupdate.nombre改成tarea.nombre即可。
修改后的完整代码示例
def modificartarea(request, id): tarea = get_object_or_404(Tarea, id=id) data = { 'tarea': CrearTareaForm(instance=tarea) } if request.method=="POST": required_fields = ['nombre', 'descripcion', 'inicio', 'termino', 'repetible', 'activo', 'estado', 'creador', 'tarea_anterior'] # 简化字段校验逻辑,更简洁 if all(request.POST.get(field) for field in required_fields): # 直接操作已获取的tarea实例 tarea.nombre = request.POST.get('nombre') tarea.descripcion = request.POST.get('descripcion') tarea.inicio = request.POST.get('inicio') tarea.termino = request.POST.get('termino') tarea.repetible = request.POST.get('repetible') tarea.activo = request.POST.get('activo') tarea.estado = EstadoTarea.objects.get(pk=request.POST.get('estado')) tarea.creador = Empleado.objects.get(rut=request.POST.get('creador')) tarea.tarea_anterior = Tarea.objects.get(pk=request.POST.get('tarea_anterior')) cursor = connection.cursor() # 传入id参数给存储过程,指定要修改的记录 cursor.execute(f"call SP_modificar_tarea('{id}', '{tarea.nombre}', '{tarea.descripcion}', '{tarea.inicio}', '{tarea.termino}', '{tarea.repetible}', '{tarea.activo}', '{str(tarea.estado.id)}', '{str(tarea.creador.rut)}', '{str(tarea.tarea_anterior.id)}')") messages.success(request, f"La tarea {tarea.nombre} se edito correctamente ") return render(request, 'app/modificartarea.html', data) else: return render(request, 'app/modificartarea.html', data)
核心说明
- 函数开头获取的
tarea实例就是你要修改的目标记录,直接复用它能避免冗余对象创建,也能保证和数据库中要修改的记录关联。 - 存储过程必须接收要修改的记录ID,否则无法完成精准更新,这是当前代码的核心疏漏。
- 用
all()函数简化字段校验逻辑,让代码更简洁易维护。
内容的提问来源于stack exchange,提问作者Cristobal Novoa
相关产品推荐
相关产品推荐

