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

基于类的视图(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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:31:14