基于类的视图(ListView)实现项数值减10功能求助
在Django ListView中实现点击按钮减数值的功能
1. 改造ListView类,添加POST请求处理
ListView默认只响应GET请求,要处理按钮提交的POST请求,需要重写post方法,把原函数视图里的逻辑迁移进来:
from django.views.generic import ListView from django.shortcuts import get_object_or_404, redirect from .models import Swimmers class SwimmersListView(ListView): model = Swimmers template_name = "accounts/swimmers_list.html" # 替换为你的列表模板路径 context_object_name = "swimmers" # 模板中使用的列表变量名 def post(self, request, *args, **kwargs): # 获取要修改的Swimmers实例主键 pk = request.POST.get("pk") if pk: sw = get_object_or_404(Swimmers, id=pk) sw.sessions -= 10 # 简化原代码的赋值逻辑 sw.save() # 区分AJAX请求和普通请求:AJAX返回片段,普通请求重定向回列表页 if request.headers.get("X-Requested-With") == "XMLHttpRequest": return render(request, "accounts/modals/swimming/_vw_table.html", {"sw": sw}) return redirect("swimmers_list") # 替换为你的ListView对应的URL name
2. 配置ListView的URL
在urls.py中添加ListView的路由(已有则跳过):
path("swimmers/", views.SwimmersListView.as_view(), name="swimmers_list"),
3. 修改模板中的表单
根据你需要的提交方式(刷新页面/无刷新更新)调整模板:
普通表单提交(刷新页面)
在列表模板的每个Swimmers条目里,添加指向ListView的表单,传递主键:
{% for sw in swimmers %} <div class="swimmer-entry"> <p>剩余课时: {{ sw.sessions }}</p> <form method="post" action="{% url 'swimmers_list' %}"> {% csrf_token %} <!-- 隐藏字段传递当前条目的pk --> <input type="hidden" name="pk" value="{{ sw.pk }}"> <button type="submit" class="float-right btn btn-primary">REDUCE SESSION</button> </form> </div> {% endfor %}
AJAX提交(无刷新更新)
如果想要和原函数视图一样无刷新更新,修改表单并添加JS逻辑:
{% for sw in swimmers %} <div class="swimmer-entry" id="swimmer-{{ sw.pk }}"> <!-- 引用原有的表格片段 --> {% include "accounts/modals/swimming/_vw_table.html" with sw=sw %} <form class="post-form" data-pk="{{ sw.pk }}"> {% csrf_token %} <div class="col float-right"> <button type="submit" class="float-right btn btn-primary" name="button">REDUCE SESSION</button> </div> </form> </div> {% endfor %} <script> // 给每个表单绑定提交事件 document.querySelectorAll(".post-form").forEach(form => { form.addEventListener("submit", function(e) { e.preventDefault(); const pk = this.dataset.pk; fetch("{% url 'swimmers_list' %}", { method: "POST", headers: { "X-CSRFToken": document.querySelector("[name=csrfmiddlewaretoken]").value, "X-Requested-With": "XMLHttpRequest" // 标记为AJAX请求 }, body: new FormData(this) }) .then(res => res.text()) .then(html => { // 替换当前条目的内容 document.getElementById(`swimmer-${pk}`).innerHTML = html; }); }); }); </script>
关键注意点
- 必须添加
{% csrf_token %}防止跨站请求伪造 - 重写
post方法时,要兼顾AJAX和普通请求两种场景 - 如果你的ListView有额外上下文数据,确保
get_context_data方法不受影响
内容的提问来源于stack exchange,提问作者d3vkidhash
相关产品推荐
相关产品推荐

