Django:如何使用modal来删除对象?

qyswt5oh  于 2023-06-25  发布在  Go
关注(0)|答案(1)|浏览(129)

在食物对象列表的索引页面上,我包含了一个按钮,用于删除未使用的对象。delete按钮启动Bootstrap 5模式删除表单。但是当我单击“删除”按钮时,抛出的错误包括索引页的名称。在下面的代码中,在哪里以及如何修复这个问题?
删除时需要的url:.../food/1/delete
页面未找到:Request URL: http://127.0.0.1:8000/food/foodIndex/1/delete
值得注意的是,404错误将请求视为GET而不是POST
[我试图通过重新创建一个工作的PHP项目来学习Python和Django。所有的HTML和JavaScript都来自这个项目。
食品/www.example.com urls.py:

urlpatterns = [
    path('foodIndex/', views.foodIndex, name="foodIndex"),
    path('<int:id>/edit/', views.foodEdit, name="foodEdit"),
    path('<int:id>/foodDelete/', views.foodDelete, name = "foodDelete")
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

注意:path('foodIndex/<int:id>/foodDelete/',...不能解决问题
模板包含在“.../food/foodIndex.html”中:

{% if allFoods.count > 0 %}
    {% for food in allFoods %}
        <tr>
            <td data-foodid="{{ food.id }}">{{ food }}</td>
            <td><a class="btn p-0" href='{% url "food:foodEdit" food.id %}'>Edit</a></td>
            {% if food.used == False %}
            <td><button id='btn_delete' type="button" class="btn p-0" data-bs-toggle="modal" data-bs-target="#modal-delete" data-bs-foodid='{{ food.id }}' data-bs-foodname='{{ food }}'>Delete</button></td>
            {% endif %}
        </tr>
    {% endfor %}
{% else %}
    <tr>
        <td colspan="3">no records found</td>
    </tr>
{% endif %}

“../food/foodIndex.html”中的模态:

<div id="modal-delete" class="modal fade" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Delete food item</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                <form >
                    <button id='food-delete' class="btn btn-warning" type="submit">Delete</button>
                </form>
            </div>
        </div>
    </div>
</div>

删除表单:

{<form method="POST" action="{% url 'food:foodDelete' pk=food.id %}" onsubmit="return confirm('Are you sure you want to delete this item?');">
    <button class="btn">Delete</button>
</form>}

modal的javascript:

const deleteModal = document.getElementById('modal-delete');
deleteModal.addEventListener('show.bs.modal', event => {
    const button = event.relatedTarget
    const foodName = button.getAttribute('data-bs-foodname')
    const foodId = button.getAttribute('data-bs-foodid')
    const modalBodyInput = deleteModal.querySelector('.modal-body ')
    const modalFooterButtons= deleteModal.querySelector('form')

    modalBodyInput.textContent = `Confirm deletion of ${foodName}`
    modalFooterButtons.setAttribute('action',`${foodId}/delete`)
}
);
oxosxuxt

oxosxuxt1#

问题在于你如何构建你的URL。

deleteModal.addEventListener('show.bs.modal', event => {
    ...
    modalFooterButtons.setAttribute('action',`${foodId}/delete`)
}
);

这将始终只产生some-id/delete作为您的操作,您没有构建完整的路径。一个简单的解决方案是使用DTL来使用reverse resolution构建URL,就像在delete form代码块中一样。
但是,可以将其用作表delete按钮的属性(您可以只替换data-bs-foodid

<button 
    id='btn-delete' 
    class="btn-warning" 
    data-bs-toggle="modal" 
    data-bs-target="#modal-delete" 
    data-bs-foodname='{{ food }}' 
    data-bs-url="{% url 'food:foodDelete' food.id %}"
>
    Delete
</button>

然后,我们检索它并使用与JavaScript相同的方法在表单上设置这些值:

deleteModal.addEventListener('show.bs.modal', event => {
    ...
    const deleteForm= deleteModal.querySelector('form');
    const url = button.getAttribute('data-bs-url');
    deleteForm.setAttribute('action', url);
    deleteForm.setAttribute('method', 'post');
});

完整示例

foodIndex.html(带食物的table)

<table class="table">
    <thead>
        <tr>
        <th scope="col">Name</th>
        <th scope="col" colspan="2">Actions</th>
        </tr>
    </thead>
    <tbody>
    {% if allFoods.count > 0 %}
        {% for food in allFoods %}
        <tr>
            <th scope="row">{{food.name}}</th>
            <td><button>Edit</button></td>
            <td>
                <button 
                    id='btn-delete' 
                    class="btn-warning" 
                    data-bs-toggle="modal" 
                    data-bs-target="#modal-delete" 
                    data-bs-foodname='{{ food }}' 
                    data-bs-url="{% url 'food:foodDelete' food.id %}"
                >
                    Delete
                </button>
            </td>
        </tr>
        {% endfor %}
    {% else %}
        <tr>
            <td colspan="3">no records found</td>
        </tr>
    {% endif %}
    </tbody>
</table>

foodIndex.html(Modal - Note {% csrf_token %}

<div id="modal-delete" class="modal fade" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Delete food item</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                <form>
                    {% csrf_token %}
                    <button id='food-delete' class="btn btn-danger" type="submit">Delete</button>
                </form>
            </div>
        </div>
    </div>
</div>

foodIndex.html(脚本)

<script>
    const deleteModal = document.getElementById('modal-delete');

    deleteModal.addEventListener('show.bs.modal', event => {
        const button = event.relatedTarget;
        const foodName = button.getAttribute('data-bs-foodname');
        const url = button.getAttribute('data-bs-url');
        const modalBodyInput = deleteModal.querySelector('.modal-body ');

        modalBodyInput.textContent = `Confirm deletion of ${foodName}`;

        const deleteForm= deleteModal.querySelector('form');
        deleteForm.setAttribute('action', url);
        deleteForm.setAttribute('method', 'post');
    });
</script>

相关问题