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

在Django中实现无需提交按钮的下拉框值实时更新

实现Django下拉选择自动同步数据库(无需更新按钮)

要实现用户切换KPI下拉选项后自动同步到数据库,需要结合后端API视图、模板数据绑定和前端AJAX请求三部分完成,具体步骤如下:


1. 后端添加KPI更新视图

在views.py中新增处理POST请求的视图,接收前端传来的Usecase ID和KPI ID,更新数据库中的外键关联:

from django.http import JsonResponse
from django.views.decorators.http import require_POST

@user_login_required
@require_POST
def update_usecase_kpi(request):
    usecase_id = request.POST.get('usecase_id')
    kpi_id = request.POST.get('kpi_id')
    
    try:
        usecase = Usecase.objects.get(usecase_id=usecase_id)
        kpi = Kpi.objects.get(id=kpi_id)
        usecase.kpi = kpi
        usecase.save()
        return JsonResponse({'status': 'success', 'kpi_name': kpi.kpi_name})
    except (Usecase.DoesNotExist, Kpi.DoesNotExist):
        return JsonResponse({'status': 'error', 'message': '数据不存在'}, status=404)

在urls.py中添加对应路由:

path('usecase/<str:ucid>/update-kpi/', views.update_usecase_kpi, name='update_usecase_kpi'),

2. 修改模板,添加数据标识和事件绑定

更新模板下拉列表部分,给每个选项绑定KPI ID,标记当前Usecase的ID,方便前端获取数据:

{% if usecase_details is not none and usecase_details %}
<div class="card card-body shadow-sm mb-4 mb-lg-0">
    {% for result in usecase_details %}
    <!-- 省略其他代码 -->
    <ul class="list-group list-group-flush">
        <li class="list-group-item d-flex align-items-center justify-content-between px-0 border-bottom">
            <div class="btn-group">
                <!-- 给显示当前KPI的按钮加唯一ID,方便后续更新文本 -->
                <button type="button" class="btn btn-secondary" id="current-kpi-{{ result.usecase_id }}">
                    KPI: {{ result.kpi.kpi_name }}
                </button>
                <button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false">
                    <svg class="icon icon-xs" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg>
                </button>
                <ul class="dropdown-menu">
                    {% for kpi in uckpi %}
                    <!-- 添加data属性存储关键数据,绑定点击事件 -->
                    <li>
                        <a class="dropdown-item" 
                           data-usecase-id="{{ result.usecase_id }}" 
                           data-kpi-id="{{ kpi.id }}"
                           data-kpi-name="{{ kpi.kpi_name }}">
                            {{ kpi.kpi_name }}
                        </a>
                    </li>
                    {% endfor %}
                </ul>
            </div>
        </li>
    </ul>
    {% endfor %}
</div>
{% endif %}

<!-- 引入Django CSRF令牌,AJAX POST请求必须携带 -->
{% csrf_token %}

3. 添加前端AJAX逻辑

在模板底部添加JS代码,监听下拉选项点击事件,发送请求更新数据库并同步页面显示:

<script>
// 获取CSRF令牌
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;

// 事件委托监听下拉选项点击
document.addEventListener('click', function(e) {
    if (e.target.classList.contains('dropdown-item')) {
        const usecaseId = e.target.dataset.usecaseId;
        const kpiId = e.target.dataset.kpiId;
        const kpiName = e.target.dataset.kpiName;
        
        // 发送POST请求到后端更新接口
        fetch(`/usecase/${usecaseId}/update-kpi/`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'X-CSRFToken': csrftoken
            },
            body: `usecase_id=${usecaseId}&kpi_id=${kpiId}`
        })
        .then(response => response.json())
        .then(data => {
            if (data.status === 'success') {
                // 更新页面上的KPI显示文本
                document.getElementById(`current-kpi-${usecaseId}`).textContent = `KPI: ${data.kpi_name}`;
                // 关闭下拉菜单
                const dropdown = new bootstrap.Dropdown(e.target.closest('.btn-group'));
                dropdown.hide();
            } else {
                alert('更新失败:' + data.message);
            }
        })
        .catch(error => {
            console.error('请求出错:', error);
            alert('更新失败,请稍后重试');
        });
    }
});
</script>

关键说明

  • CSRF令牌:Django默认启用CSRF保护,AJAX POST请求必须携带X-CSRFToken头,否则会被拒绝。
  • 事件委托:使用document.addEventListener监听点击,避免动态生成的下拉项无法绑定事件的问题。
  • 错误处理:前后端都添加了错误捕获,确保更新失败时能给出明确提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 23:27:18