将 Django 和 Bootstrap 5 Modal 与 Ajax 结合使用
Posted
技术标签:
【中文标题】将 Django 和 Bootstrap 5 Modal 与 Ajax 结合使用【英文标题】:Combine Django and Bootstrap 5 Modal with Ajax 【发布时间】:2022-01-04 01:39:39 【问题描述】:如何使用 obj.pk 拥有可以像某个帖子一样定位对象 pk 的按钮/链接,然后打开模态 edit modal 和 delete modal。
然后模态框可以使用 AJAX(Fetch API 或 Jquery)在不刷新的情况下成功编辑和删除。我有问题以模态为目标打开具有某些 PK 的帖子。我不能使用 id="editPostobj.id" 或 id="deletePostobj.id" 来定位模态,因为我需要将模态放在 forloop 中,然后每个模态都会重复发帖。
这里是一些代码:
% for obj in page_obj %
<li>
<a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#editPost" href="% url 'post-update' obj.pk %">Edit Post</a>
</li>
<li>
<a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#deletePost" href="% url 'post-delete' obj.pk %">Delete Post</a>
</li>
<div id="postobj.id" class="box-content">
<p class="box-text mb-2"> obj.content </p>
<span class="username"> obj.username </span>
</div>
% endfor %
<div class="modal fade" id="deletePost" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Delete Post?</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete your post?</p>
</div>
<div class="modal-footer">
<button type="button" class="rvg-button-small" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="rvg-button-small">Delete</button>
</div>
</div>
</div>
</div>
我实现AJAX的方式是使用
<a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#editPost" onclick="EditPost(' obj.id ')">
<a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#deletePost" onclick="DeletePost(' obj.id ')">
const DeletePost = (post_id) =>
fetch("/" + post_id + "/delete/",
method: "POST",
credentials: 'same-origin',
headers: "X-CSRFToken": getCookie("csrftoken") ,
)
.then((res) => res.json())
.then((data) =>
document.getElementById(`post$post_id`).remove()
console.log("successfully deleted")
).catch((e) => alert("Error deleting post."));
【问题讨论】:
【参考方案1】:您可以使用 data-<something>
以及 bootstrap 使用 data-bs-<something>
将参数传递给您的模式。
<a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#deletePost" data-object-id=" obj.id " onclick="DeletePost()">
然后使用 js,在 DeletePost
内,您需要提取 pk
或您传递给它的任何其他参数。阅读更多关于dataset
here的信息。
另一种选择是使用anonymous function 包装您的函数,以将参数传递给内部函数,最后调用外部(匿名)函数。
在这种情况下,我使用arrow function 语法,但等效于函数定义的常规语法:
<a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#deletePost" onclick="(() => DeletePost( obj.id ) )()">
我会推荐第一个选项,因为(我认为)当您需要将多个参数传递给函数但其中任何一个都应该工作时,它对于将来的使用更加灵活。
编辑: 我之前忘了提这个。如果您使用第一个选项,请确保在 html 元素中调用您的函数时传递事件,以便获取点击目标元素和附加到它的数据集。
您的元素应如下所示:
<a ... onclick="DeletePost(event)">
.
您的 js 函数将接收事件作为参数:
const DeletePost = (event) =>
const btn = event.target; // the clicked button.
const object_id = btn.dataset.objectId;
console.log(object_id); // should display the right id.
编辑 2:
为了能够在模态中调用您的 Django URL:
删除 for 循环内 <a>
元素中的 href
属性,或将标签 <a>
替换为 <button>
,保留引导程序显示模式所需的属性。
这将防止在不先显示模式的情况下过早调用您的 Django 视图。
同时保留data-object-id
属性。
在模态代码中,将页脚中的 <button>
元素替换为如下内容:
<a id="delete-post-btn" class="rvg-button-small" href="% 'DeletePost' %">Delete</a>
请记住,在此阶段,href
不完整,因为缺少 object-id
。
-
为modal创建一个事件监听器,监听事件'shown.bs.modal'知道modal什么时候打开并提取对象id完成
href
属性:
document
.getElementById('deletePost')
.addEventListener('shown.bs.modal', (event) =>
// The modal is open and the object-id can be extracted.
event.preventDefault(); // this step may not be needed.
const btn = event.relatedTarget; // this is the button that contains the data-<something> attrs
const objectId = btn.dataset.objectId;
// Now we add the object-id value to the href.
const modal_btn = document.getElementById('delete-post-btn');
modal_btn.href += String(objectId);
)
现在href
应该是完整的,并且按钮应该能够使用正确的 object-id 调用 Django 视图 URL。
【讨论】:
我用第一种方法试过了,但只得到对象的第一个元素,而不是我点击的那个 请更新您的问题,添加您如何从数据集中提取值。 @AwesomeLerman 我更新了我的答案,对如何从数据集中提取值进行了更多解释。 感谢您的回答,方法是成功的,但是如何使引导模式(弹出)中的按钮成为删除帖子的按钮? DeletePost( ) 函数当前位于下拉项中,而不是模式中的按钮中。模态在 forloop 之外,因此无法获取对象 ID。如何将数据集值从 DeletePost 函数传递到引导模式? 对不起,我是 javascript 新手:/以上是关于将 Django 和 Bootstrap 5 Modal 与 Ajax 结合使用的主要内容,如果未能解决你的问题,请参考以下文章
django-bootstrap-v5 DecimalField 在 ModelForm 类中抛出错误
Django crudbuilder & Bootstrap 日期选择器
如何将 bootstrap 5 与 webpack 加载器一起使用?