如何让删除按钮精准删除指定Post?问题求助
问题:删除弹窗无法匹配对应Post,始终操作第一篇内容
我设置了带弹窗的删除按钮,但该按钮无法正确识别目标Post,总是删除第一篇Post;弹窗也无法显示对应Post的标题,始终展示第一篇Post的标题,尽管我使用了相同的模板标签。
相关代码
views.py
@login_required() def delete(request, id): poost = get_object_or_404(post, pk=id) if request.user == poost.author: poost.delete() messages.error(request, f'Post deleted!') return redirect("/")
post.html(删除弹窗及按钮所在模板)
<div class="modal" tabindex="-1" role="dialog"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title">Modal title</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p>Modal body text goes here.</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-primary">Save changes</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> </div> </div> </div> </div> <!-- Modal --> <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Are you sure?</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p class="text-muted"> Do you really want to delete {{ post.title }}? This process cannot be undone.</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> <a href="{% url 'delete' post.id %}"><button type="button" class="btn btn-danger">Delete</button></a> </div> </div> </div> </div> <div class="container" style="min-height: 100vh; width: 100%;"> <div class="row"> <div class="col-lg 3 col-md-3 col-sm-12 col-xs-12"> <div style="margin-top: 60px"></div> <div class="card-deck text-center"> <div class="card mb-4 box-shadow"> <div class="card-header" id="linkilink"> <h4 class="my-0 font-weight-normal" style="font-family: Georgia, serif; font-size: 25px;">{{post.title}}</h4> </div> <div class="card-body" style="margin-top: 20px"> {{ post.body|truncatewords_html:30 }} <hr> <p> <a><img class="rounded-circle article-img" src="{{ post.author.profile.image.url }}" width="75" height="75"></a> <div style="color: rgb(133, 131, 131);">Author:<a href="{% url 'user_posts' post.author.username %}"> {{ post.author }} </a></div> </p> <a href="{% url 'detail' post.id %}" class="btn btn-info btn-small" id="readbutton">Read More <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-three-dots" viewBox="0 0 16 16"> <path d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z"/> </svg></a> {% if user.is_authenticated %} {% if user == post.author%} <a href="{% url 'update' post.id %}" class="btn btn-primary btn-small" >Edit</a> <a href="#" class="btn btn-danger btn-small" data-toggle="modal" data-target="#exampleModal" >Delete <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16"> <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6Z"/> <path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1ZM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118ZM2.5 3h11V2h-11v1Z"/> </svg></a> {% endif %} {% endif %} </div> </div> </div>
urls.py
from django.urls import path from . import views from .views import PostUpdateView urlpatterns = [ path('new', views.new, name='new'), path('<int:id>', views.detail, name='detail'), path('delete/<int:id>', views.delete, name='delete'), path('search/', views.search_post, name='search-view'), path('menu/',views.side_bar, name='menu'), path('<int:pk>/update/', PostUpdateView.as_view(success_url="/"), name='update'), ]
问题原因
核心问题是所有弹窗共用同一个固定ID exampleModal。HTML要求页面内ID必须唯一,浏览器只会匹配到第一个拥有该ID的弹窗元素。因此无论点击哪个Post的删除按钮,都会触发第一篇Post对应的弹窗,跳转的删除链接也始终是第一篇的ID。
解决方案
1. 为每个Post生成唯一弹窗ID
修改post.html中的弹窗和删除按钮,将弹窗ID与当前Post的ID绑定,确保每个弹窗唯一:
修改后的弹窗代码
<!-- 每个Post对应唯一弹窗 --> <div class="modal fade" id="deleteModal-{{ post.id }}" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel-{{ post.id }}" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="deleteModalLabel-{{ post.id }}">Are you sure?</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p class="text-muted"> Do you really want to delete {{ post.title }}? This process cannot be undone.</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> <a href="{% url 'delete' post.id %}"><button type="button" class="btn btn-danger">Delete</button></a> </div> </div> </div> </div>
修改后的删除按钮代码
<a href="#" class="btn btn-danger btn-small" data-toggle="modal" data-target="#deleteModal-{{ post.id }}" >Delete <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16"> <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6Z"/> <path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1ZM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118ZM2.5 3h11V2h-11v1Z"/> </svg></a>
2. 移除冗余弹窗
删除post.html开头那个未绑定任何Post数据的默认弹窗,避免代码冗余。
可选优化(动态弹窗)
如果不想渲染多个弹窗,可以用JavaScript动态修改单个弹窗的内容和删除链接:
- 保留一个通用弹窗,将其中的
{{ post.title }}和删除链接替换为占位符 - 在删除按钮上添加
data-post-id和data-post-title属性,存储当前Post的ID和标题 - 编写JS监听按钮点击事件,动态更新弹窗内容和链接
不过对于小型项目,每个Post对应唯一弹窗的实现方式更简单直接,无需额外JS逻辑。
内容的提问来源于stack exchange,提问作者Rin Hyakuya
相关产品推荐
相关产品推荐

