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

Django点击下载按钮时自动更新模型Choice字段值的实现问题

解决方案

以下两种方案均可实现点击下载按钮自动更新状态、无需跳转额外页面的需求,可根据实际场景选择:


方案1:纯后端实现(无需JS,兼容性最优)

无需引入前端脚本,逻辑最简单,点击后浏览器自动触发下载,当前页面无跳转。

步骤1:修改视图函数(views.py)

原有表单逻辑完全可以移除,直接更新状态后返回文件下载响应即可:

from django.http import FileResponse
from django.shortcuts import get_object_or_404

def change_status(request, pk):
    oficio = get_object_or_404(Oficio, folio=pk)
    # 仅当状态为NUEVO时更新为LEIDO
    if oficio.estatus == Oficio.Estatus.NUEVO and request.method == "POST":
        oficio.estatus = Oficio.Estatus.LEIDO
        oficio.usuario = request.user
        # 仅更新指定字段,提升操作效率
        oficio.save(update_fields=["estatus", "usuario"])
    # 直接返回文件响应,触发浏览器下载
    response = FileResponse(oficio.documento.open(), as_attachment=True)
    return response

步骤2:修改模板代码(template.html)

移除按钮内部嵌套的a标签(不符合HTML规范,容易触发行为冲突),改为纯提交按钮:

<form method="POST" action="{% url 'oficios:status' oficio.folio %}">
   {% csrf_token %}
   <button type="submit" class="btn btn-primary btn-lg" title="Descargar">
       <i class="fas fa-file-download"></i>
   </button>
</form>

冗余代码清理

forms.py中的UpdateStatus表单已经完全没有使用场景,可以直接删除。


方案2:AJAX无感知更新(体验最优)

如果需要点击后页面上的状态标签自动同步更新、无需用户手动刷新页面,可采用该方案:

步骤1:修改视图函数(views.py)

返回JSON格式的响应供前端处理:

from django.http import JsonResponse
from django.shortcuts import get_object_or_404

def change_status(request, pk):
    if request.method != "POST":
        return JsonResponse({"success": False, "msg": "请求方法错误"})
    oficio = get_object_or_404(Oficio, folio=pk)
    new_status = oficio.get_estatus_display()
    if oficio.estatus == Oficio.Estatus.NUEVO:
        oficio.estatus = Oficio.Estatus.LEIDO
        oficio.usuario = request.user
        oficio.save(update_fields=["estatus", "usuario"])
        new_status = oficio.get_estatus_display()
    return JsonResponse({
        "success": True,
        "new_status": new_status
    })

步骤2:修改模板代码(template.html)

给状态标签添加唯一标识,绑定按钮点击事件发送AJAX请求:

<!-- 给原有状态标签添加id,方便后续更新内容 -->
<span class="badge bg-primary" id="status_{{oficio.folio}}">{{ oficio.get_estatus_display }}</span>

<!-- 下载按钮 -->
<button type="button" class="btn btn-primary btn-lg download-btn" 
        data-folio="{{oficio.folio}}" 
        data-doc-url="{{oficio.documento.url}}"
        title="Descargar">
    <i class="fas fa-file-download"></i>
</button>

<!-- 全局CSRF Token,AJAX请求用 -->
{% csrf_token %}

<script>
// 批量绑定所有下载按钮的点击事件
document.querySelectorAll(".download-btn").forEach(btn => {
    btn.addEventListener("click", function() {
        const folio = this.dataset.folio;
        const docUrl = this.dataset.docUrl;
        const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;

        // 发送AJAX请求更新状态
        fetch(`/oficios/status/${folio}/`, {
            method: "POST",
            headers: {
                "X-CSRFToken": csrfToken,
            },
        }).then(res => res.json())
        .then(data => {
            if (data.success) {
                // 自动更新页面上的状态标签
                document.getElementById(`status_${folio}`).textContent = data.new_status;
                // 触发文件下载
                window.open(docUrl, "_blank");
            }
        });
    });
});
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 12:36:01