如何在Django表单提交前将JS获取的选中审批人传递至模板?
问题描述
在Django开发中,需要在表单提交前获取用户选中的审批人并做可用性校验。目前已能获取选中审批人的ID,但模板中通过{% for entry in form.approvers %}会显示所有审批人,希望点击「查看可用性」按钮后,仅展示选中的审批人,并通过视图的冲突查询逻辑显示其是否可用。
解决方案
步骤1:修改AJAX代码,传递选中审批人ID
当前AJAX未将选中的审批人ID传给后端,需收集ID并作为请求参数发送:
$("#avail").on("click", function(event) { var modalavail = document.getElementById("myModalavail"); var markedCheckbox = document.querySelectorAll('input[type="checkbox"]:checked'); // 收集选中的审批人ID数组 var approverIds = Array.from(markedCheckbox).map(checkbox => checkbox.value); event.preventDefault(); $(window).unbind('beforeunload'); $.ajax({ method: 'GET', headers: { "X-CSRFToken": token }, url: "{% url 'check_approver_availability' %}", // 需在urls.py中定义该路由 data: { 'approver_ids': approverIds, 'start_time': $('#id_start_time').val(), // 对应表单中开始时间输入框ID 'end_time': $('#id_end_time').val() // 对应表单中结束时间输入框ID }, success: function(resp) { modalavail.style.display = "block"; // 清空容器并渲染返回的HTML内容 $('.table56').html(resp.html); }, error: function (request, status, error) { console.log(request.responseText); showAjaxFormErrors(JSON.parse(request.responseText)); $('html, body').animate({ scrollTop: 0 }, 50); }, }); });
步骤2:添加视图处理函数,返回选中审批人的可用性数据
在views.py中新增视图,接收参数后查询冲突并返回渲染后的HTML片段:
from django.shortcuts import render from django.http import JsonResponse from .models import DailyPlannerEvent, User from django.template.loader import render_to_string def check_approver_availability(request): if request.method == 'GET': approver_ids = request.GET.getlist('approver_ids') start_time = request.GET.get('start_time') end_time = request.GET.get('end_time') # 获取选中的活跃审批人对象 approvers = User.objects.filter(id__in=approver_ids, is_active=True) # 为每个审批人计算可用性 approver_availability = [] for approver in approvers: # 查询该审批人的时间冲突 start_conflict = DailyPlannerEvent.objects.filter( approvers=approver, start_time__range=(start_time, end_time) ).exists() end_conflict = DailyPlannerEvent.objects.filter( approvers=approver, end_time__range=(start_time, end_time) ).exists() during_conflict = DailyPlannerEvent.objects.filter( approvers=approver, start_time__lte=start_time, end_time__gte=end_time ).exists() # 存在任意冲突则标记为不可用 is_available = not (start_conflict or end_conflict or during_conflict) approver_availability.append({ 'user': approver, 'is_available': is_available }) # 渲染模板片段 html = render_to_string('approver_availability_modal_content.html', { 'approver_availability': approver_availability }) return JsonResponse({'html': html})
步骤3:创建专用模板片段渲染选中审批人
新建模板文件approver_availability_modal_content.html,仅渲染选中的审批人和可用性:
<div class="table56"> {% for item in approver_availability %} <table class="table57"> <thead> <tr> <th class="title156">Name</th> <th class="title118">Available?</th> </tr> </thead> <tbody> <tr> <td class="title156">{{ item.user.get_full_name }}</td> <td class="title117">{{ "Yes" if item.is_available else "No" }}</td> </tr> </tbody> </table> {% endfor %} </div>
步骤4:配置URL路由
在urls.py中添加对应路由:
from django.urls import path from .views import check_approver_availability urlpatterns = [ # 其他路由... path('check-approver-availability/', check_approver_availability, name='check_approver_availability'), ]
步骤5:调整原模板中的模态框结构
原模板移除form.approvers循环,留空容器等待AJAX填充:
<!-- 模态框 --> <div id="myModalavail" style="display:none;"> <div class="modal-content"> <!-- 动态内容容器 --> <div class="table56"></div> <input type="hidden" id="modal-approvers"> <button type="button" class="button210" id="modalcloseavail">Close</button> </div> </div>
关键说明
- 不再依赖原视图的
get_context_data传递冲突数据,通过专门的AJAX视图处理选中审批人的可用性校验 - 使用
render_to_string渲染模板片段,避免整页刷新 - AJAX请求中传递事件起止时间,确保冲突查询的准确性
- 原表单的
approvers字段保持不变,仅在可用性校验时动态筛选选中项
内容的提问来源于stack exchange,提问作者Steve Smith
相关产品推荐
相关产品推荐

