【问题标题】:Combine Django and Bootstrap 5 Modal with Ajax将 Django 和 Bootstrap 5 Modal 与 Ajax 结合使用
【发布时间】:2022-01-04 01:39:39
【问题描述】:

如何使用 {{obj.pk}} 拥有可以像某个帖子一样定位对象 pk 的按钮/链接,然后打开模态 edit modaldelete modal

然后模态框可以使用 AJAX(Fetch API 或 Jquery)在不刷新的情况下成功编辑和删除。我有问题以模态为目标打开具有某些 PK 的帖子。我不能使用 id="editPost{{obj.id}}" 或 id="deletePost{{obj.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="post{{obj.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."));
}

【问题讨论】:

    标签: javascript python html django ajax


    【解决方案1】:

    您可以使用 data-&lt;something&gt; 以及 bootstrap 使用 data-bs-&lt;something&gt; 将参数传递给您的模式。

    <a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#deletePost" data-object-id="{{ obj.id }}" onclick="DeletePost()">
    

    然后使用 js,在 DeletePost 内,您需要提取 pk 或您传递给它的任何其他参数。阅读更多关于datasethere的信息。

    另一种选择是使用anonymous function 包装您的函数,以将参数传递给内部函数,最后调用外部(匿名)函数。

    在这种情况下,我使用arrow function 语法,但等效于函数定义的常规语法:

    <a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#deletePost"  onclick="(() => { DeletePost({{ obj.id }}) })()">
    

    我会推荐第一个选项,因为(我认为)当您需要将多个参数传递给函数但其中任何一个都应该工作时,它对于将来的使用更加灵活。

    编辑: 我之前忘了提这个。如果您使用第一个选项,请确保在 html 元素中调用您的函数时传递事件,以便获取点击目标元素和附加到它的数据集。

    您的元素应如下所示: &lt;a ... onclick="DeletePost(event)"&gt;.

    您的 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:

    1. 删除 for 循环内 &lt;a&gt; 元素中的 href 属性,或将标签 &lt;a&gt; 替换为 &lt;button&gt;,保留引导程序显示模式所需的属性。 这将防止在不先显示模式的情况下过早调用您的 Django 视图。 同时保留data-object-id 属性。

    2. 在模态代码中,将页脚中的 &lt;button&gt; 元素替换为如下内容:

    <a id="delete-post-btn" class="rvg-button-small" href="{% 'DeletePost' %}">Delete</a>
    

    请记住,在此阶段,href 不完整,因为缺少 object-id

    1. 为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 新手:/
    猜你喜欢
    • 1970-01-01
    • 2023-02-05
    • 2022-01-02
    • 2016-09-15
    • 2021-02-01
    • 2022-08-22
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    相关资源
    最近更新 更多