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

Django如何从模板向视图传递ID以实现数据更新?

问题分析与解决方案

当前实现存在几个关键问题,导致点击更新链接后无法触发PostgreSQL函数执行:

  1. 点击<a>标签发起的是GET请求,但视图仅在POST分支执行数据库操作,因此会直接进入else分支,不会触发函数调用。
  2. 视图中直接拼接SQL字符串存在SQL注入风险,同时resolve_item是模型实例对象,直接拼入SQL会导致语法错误。
  3. 未处理数据库事务提交(如果PostgreSQL函数涉及数据修改,需要手动提交事务)。

可行方案

1. 修正视图函数(views.py)

  • 使用参数化查询避免SQL注入
  • 正确传递函数所需的参数(假设resolve_clearance_item需要的是cl_itemid数值)
  • 处理事务提交(针对数据修改类函数)
  • 重定向回列表页,避免刷新页面重复提交
from django.db import connection
from django.shortcuts import get_object_or_404, render, redirect

def update(request, cl_itemid):
    # 先验证ID对应的记录存在
    resolve_item = get_object_or_404(Clearanceinsert, pk=cl_itemid)
    
    if request.method == "POST":
        with connection.cursor() as cursor:
            # 用参数化查询传递值,%s是PostgreSQL的占位符
            cursor.execute("SELECT resolve_clearance_item(%s)", [cl_itemid])
            # 若函数涉及数据变更,必须提交事务
            connection.commit()
        # 重定向回列表页,替换为你的列表页URL名称
        return redirect('clearance_index')
    else:
        # GET请求返回确认页面,避免误操作触发更新
        return render(request, 'clearance/confirm_update.html', {'item': resolve_item})

2. 修改模板,使用POST提交请求

更新属于数据变更操作,建议用表单发起POST请求(<a>标签默认是GET,不适合修改类操作):

<table style="width:100%">
  <tr>
      <th>cl_itemid</th>
      <th colspan="2">Actions:</th>
  </tr>
{% for data in data %}
  <tr>
      <td>{{ data.cl_itemid }}</td>
      <td>
          <form method="POST" action="{% url 'update' data.cl_itemid %}">
              {% csrf_token %}  <!-- Django强制要求的CSRF防护 -->
              <button type="submit">Update</button>
          </form>
      </td>
  </tr>
{% endfor %}
</table>

如果想保留链接样式,可用CSS将按钮模拟成链接:

<style>
.update-btn {
    background: none;
    border: none;
    color: blue;
    text-decoration: underline;
    cursor: pointer;
    padding: 0;
}
</style>

<td>
    <form method="POST" action="{% url 'update' data.cl_itemid %}">
        {% csrf_token %}
        <button type="submit" class="update-btn">Update</button>
    </form>
</td>

3. 确认URL配置正确

在urls.py中确保update的路由映射正确:

from django.urls import path
from . import views

urlpatterns = [
    # 其他路由...
    path('update/<int:cl_itemid>/', views.update, name='update'),
    path('', views.index, name='clearance_index'),  # 列表页路由,对应视图中的redirect目标
]

替代思路(Django模型封装函数)

如果resolve_clearance_item是自定义PostgreSQL函数,可以在模型中封装它,更符合Django开发规范:

from django.db import models

class Clearanceinsert(models.Model):
    cl_itemid = models.IntegerField(primary_key=True)
    # 其他模型字段...
    
    def resolve_clearance(self):
        from django.db import connection
        with connection.cursor() as cursor:
            cursor.execute("SELECT resolve_clearance_item(%s)", [self.cl_itemid])
            result = cursor.fetchone()
        connection.commit()
        return result[0] if result else None

视图中直接调用模型方法:

def update(request, cl_itemid):
    item = get_object_or_404(Clearanceinsert, pk=cl_itemid)
    if request.method == "POST":
        item.resolve_clearance()
        return redirect('clearance_index')
    else:
        return render(request, 'clearance/confirm_update.html', {'item': item})

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 22:35:20