You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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对象即可,具体调整如下:

  1. 删除新建实例的代码
    删掉 tareaupdate= Tarea()这一行,所有字段赋值直接操作已有的tarea实例。

  2. 调整字段赋值逻辑
    把所有tareaupdate.xxx替换成tarea.xxx,比如:

    tarea.nombre = request.POST.get('nombre')
    tarea.descripcion = request.POST.get('descripcion')
    # ... 其余字段同理
    
  3. 修复存储过程调用的关键问题
    你的存储过程目前缺少要修改的任务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拼接字符串比直接+拼接更安全易读,也能避免部分语法错误)

  4. 调整成功提示信息
    把提示里的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:48:27