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

Django删除视图异常:点击任意删除按钮均指向同一条目

问题描述

我想让delete_entry视图删除对应的条目,但无论点击哪个删除按钮,都会引用同一个item_id。我修改了视图,让它只打印要删除的条目而不执行删除,但不管选列表里哪个按钮,选中的都是同一个条目。

请问我的视图有问题吗?我的编辑功能正常运行,要不要把delete_entry改成和EditHealth一样的工作方式?


相关代码

Health_hub_history.html

{% for item in stats %}
<tr>
    <td>{{ item.user }}</td>
    <td>{{ item.weight }} </td>
    <td>{{ item.date }}</td>
    <td>{{ item.run_distance }}</td>
    <td>{{ item.run_time }}</td>
    <!-- Button trigger modal -->
    <td>
        <a href="edit/{{ item.id }}"><button type="button" class="btn btn-primary">
            Edit
        </button>
    </a>
    </td>
    <td>
        <button type="button" class="btn btn-danger" data-bs-toggle="modal"
            data-bs-target="#staticBackdrop">
            Delete
        </button>
    </td>
    <!-- Modal -->
    <div class="modal fade" id="staticBackdrop" data-bs-backdrop="static" data-bs-keyboard="false"
        tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="staticBackdropLabel">Are you sure you want to delete
                        this entry?</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"
                        aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    If you just need to amend something, try the edit button.
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary"
                        data-bs-dismiss="modal">Cancel</button>
                    <a href="delete/{{ item.id }}"><button class="btn btn-danger">I'm
                            sure</button></a>
                </div>
            </div>
        </div>
    </div>
</tr>
{% endfor %}

Views.py

def health_history(request):
    serialized_stats = []
    for stats in HealthStats.objects.filter(user=request.user):
        serialized_stats.append({
            "user": stats.user,
            "weight": stats.weight,
            "date": stats.date,
            "run_distance": stats.run_distance,
            "run_time": stats.run_time,
            "id": stats.id,
        })
    context = {
        "stats": serialized_stats
        }
    return render(request, 'health_hub_history.html', context)

def delete_entry(request, item_id):
    entry = get_object_or_404(HealthStats, id=item_id)
    print(entry)
    # entry.delete()
    return redirect("HealthHub:health_hub_history")

class EditHealth(UpdateView):
    model = HealthStats
    template_name = 'health_hub_edit.html'
    fields = ['weight', 'run_distance', 'run_time']

Urls.py

urlpatterns = [
    path('', views.home, name='home'),
    path('MyHealth/', views.health_hub, name='health_hub'),
    path('MyHealth/update', views.UpdateHealth.as_view(), name='health_hub_update'),
    path('MyHealth/history', views.health_history, name='health_hub_history'),
    path('favicon.ico', RedirectView.as_view(url=staticfiles_storage.url("favicon.ico"))),
    path('MyHealth/delete/<item_id>', views.delete_entry, name='health_hub_delete'),
    path('MyHealth/edit/<int:pk>', views.EditHealth.as_view(), name='health_hub_edit'),
]

Models.py

from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse


class HealthStats(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    date = models.DateTimeField(auto_now_add=True)
    weight = models.DecimalField(max_digits=5, decimal_places=2)
    run_distance = models.DecimalField(max_digits=5, decimal_places=2)
    run_time = models.DurationField()

    class Meta:
        db_table = 'health_stats'
        ordering = ['-date']

    def get_absolute_url(self):
        return reverse('HealthHub:health_hub_history')

    def __str__(self):
        return f"{self.user} | {self.date}"

解决方案

1. 修复Modal的ID冲突问题

问题核心是所有删除按钮绑定的Modal ID都是staticBackdrop,HTML中ID必须唯一,所以无论点击哪个按钮,都会触发页面中第一个(或最后一个)Modal,导致跳转的item_id固定。

修改HTML代码,给每个Modal和对应的触发按钮添加唯一ID:

{% for item in stats %}
<tr>
    <!-- ... 其他列保持不变 ... -->
    <td>
        <!-- 修改data-bs-target为带item.id的唯一ID -->
        <button type="button" class="btn btn-danger" data-bs-toggle="modal"
            data-bs-target="#staticBackdrop-{{ item.id }}">
            Delete
        </button>
    </td>
    <!-- Modal -->
    <!-- 修改Modal的id为staticBackdrop-{{ item.id }} -->
    <div class="modal fade" id="staticBackdrop-{{ item.id }}" data-bs-backdrop="static" data-bs-keyboard="false"
        tabindex="-1" aria-labelledby="staticBackdropLabel-{{ item.id }}" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <!-- 标题ID也保持唯一 -->
                    <h5 class="modal-title" id="staticBackdropLabel-{{ item.id }}">Are you sure you want to delete
                        this entry?</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal"
                        aria-label="Close"></button>
                </div>
                <!-- ... 其他Modal内容保持不变 ... -->
            </div>
        </div>
    </div>
</tr>
{% endfor %}

2. 修正URL路径的参数类型

在Urls.py中,删除路径的参数应该指定为整数类型,和编辑路径保持一致:

# 把 <item_id> 改成 <int:item_id>
path('MyHealth/delete/<int:item_id>', views.delete_entry, name='health_hub_delete'),

3. (可选)改用类视图实现删除功能

既然编辑用了UpdateView,删除可以用Django自带的DeleteView,保持代码风格统一:

修改Views.py:

from django.views.generic import DeleteView
from django.urls import reverse_lazy

# 替换原来的delete_entry函数
class DeleteHealth(DeleteView):
    model = HealthStats
    success_url = reverse_lazy('HealthHub:health_hub_history')
    # 可以自定义确认模板,或者直接用默认的
    # template_name = 'health_hub_delete_confirm.html'

修改Urls.py:

# 替换原来的delete路径
path('MyHealth/delete/<int:pk>', views.DeleteHealth.as_view(), name='health_hub_delete'),

调整HTML中的跳转链接:

<!-- 把 delete/{{ item.id }} 改成 delete/{{ item.id }}(因为DeleteView用pk参数,和item.id一致) -->
<a href="delete/{{ item.id }}"><button class="btn btn-danger">I'm sure</button></a>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 09:50:26