ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Django - 表单跳转和分页

Django - 表单跳转和分页 前端直接把对应代码加入对应表单就可以实现表单的分页和跳转表单 table classtable idtaskTable thead tr thID/th th任务详情/th th任务级别/th th执行人/th th操作/th /tr /thead tbody {% for itm in page_obj %} tr td{{ itm.id }}/td td{{ itm.content }}/td td{{ itm.get_lever_display }}/td td{{ itm.user.username|default:未分配 }}/td td input classbtn btn-primary btn-xs btn-edit typebutton value编辑 >script // 页码跳转 function jumpToPage() { const input document.getElementById(jumpPageInput); const maxPage {{ page_obj.paginator.num_pages }}; // Django 注入总页数 let page parseInt(input.value, 10); // 完善的输入校验 if (isNaN(page) || page 1) page 1; if (page maxPage) page maxPage; if (page {{ page_obj.number }}) return; // 当前页不重复刷新 // URLSearchParams 自动保留所有现有参数安全替换 page updateUrlAndGo({ page: page }); } // 回车跳转 document.getElementById(pageInput).addEventListener(keypress, function (e) { if (e.key Enter) { jumpToPage(); } }); /** * 统一处理 URL 参数跳转 * 原理读取当前 URL 中的所有参数keyword, lever, executor, page_size 等 * 仅覆盖传入的新参数其余原封不动保留彻底杜绝参数丢失。 */ function updateUrlAndGo(paramsObj) { const params new URLSearchParams(window.location.search); for (const [key, value] of Object.entries(paramsObj)) { if (value || value null || value undefined) { params.delete(key); } else { params.set(key, value); } } window.location.href ? params.toString(); } // 【重要】拦截搜索表单提交强制重置到第1页 // 防止用户在第5页搜索新关键词时因结果不足5页而显示空白 document.querySelector(form[methodget]).addEventListener(submit, function(e) { e.preventDefault(); const formData new FormData(this); const params new URLSearchParams(); for (const [key, value] of formData.entries()) { if (value ! ) params.set(key, value); } params.set(page, 1); // 搜索时始终回到第一页 window.location.href ? params.toString(); }); // 拦截搜索表单提交强制重置到第1页 const searchForm document.querySelector(form[methodget]); if (searchForm) { searchForm.addEventListener(submit, function(e) { e.preventDefault(); const formData new FormData(this); const params new URLSearchParams(); for (const [key, value] of formData.entries()) { if (value ! ) params.set(key, value); } params.set(page, 1); window.location.href ? params.toString(); }); } /scriptCSS:style /* 遮罩全屏 flex 居中 */ .modal-mask { display: none; /* 默认隐藏 */ position: fixed; /* 固定定位不随页面滚动 */ top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); z-index: 999; /* 居中全靠这三行 */ justify-content: center; /* 水平居中 */ align-items: center; /* 垂直居中 */ } /* 显示状态注意是 flex不是 block */ .modal-mask.show { display: flex; } /* 弹窗白框不需要 position、top、transform */ .modal-box { background: #fff; width: 420px; max-height: 90vh; /* 内容太多时不超出屏幕 */ overflow-y: auto; padding: 20px; border-radius: 8px; } .modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .modal-footer { text-align: right; margin-top: 15px; } /* 外层容器 */ .pagination-bar { display: flex; align-items: center; gap: 8px; margin-top: 20px; flex-wrap: wrap; } /* 翻页按钮通用 */ .page-btn { padding: 5px 10px; border: 1px solid #ddd; text-decoration: none; color: #333; border-radius: 3px; font-size: 14px; white-space: nowrap; } .page-btn:hover:not(.disabled) { background-color: #f5f5f5; border-color: #ccc; } /* 禁用状态 */ .page-btn.disabled { border-color: #eee; color: #ccc; cursor: not-allowed; } /* 页码信息文本 */ .page-info { padding: 5px 10px; color: #333; font-size: 14px; white-space: nowrap; } /* 功能分组间距 */ .page-size-group, .jump-group { display: flex; align-items: center; gap: 4px; margin-left: 8px; } /* 标签文字 */ .label-text { font-size: 14px; color: #666; white-space: nowrap; } /* 每页条数下拉框 */ .page-select { padding: 5px 10px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; } /* 跳转输入框 */ .jump-input { width: 60px; padding: 4px 8px; border: 1px solid #ddd; border-radius: 3px; text-align: center; font-size: 14px; } /* 去除 number 输入框的上下箭头可选 */ .jump-input::-webkit-inner-spin-button, .jump-input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } .jump-input { -moz-appearance: textfield; } /* GO 按钮 */ .jump-btn { padding: 4px 12px; border: 1px solid #ddd; background: #fff; border-radius: 3px; cursor: pointer; font-size: 14px; color: #333; } .jump-btn:hover { background-color: #f5f5f5; border-color: #ccc; } /style后端def task_list(request): form TaskModelForm() # 获取搜索参数 keyword request.GET.get(keyword, ).strip() lever request.GET.get(lever, ) executor request.GET.get(executor, ) # 动态构建过滤条件 condition {} if keyword: condition[content__icontains] keyword if lever: condition[lever] lever if executor: condition[user_id] executor queryset models.Task.objects.select_related(user).filter(**condition).order_by(-id) # 分页 page_size int(request.GET.get(page_size, 5)) paginator Paginator(queryset, page_size) pagenumber request.GET.get(page, 1) page_obj paginator.get_page(pagenumber) # 新增从数据库动态获取级别和执行人列表 # 假设级别存在 Levers 模型中或者 Task 模型有 lever 外键 levers models.Task.lever_choices executors models.Admin.objects.all() # 根据你的实际执行人模型名调整 context { form: form, page_obj: page_obj, page_size: page_size, keyword: keyword, lever: lever, executor: executor, levers: levers, # 级别列表 executors: executors, # 执行人列表 page_size_options: [5, 10, 20, 50], } return render(request, task_list.html, context)
返回列表