【问题标题】:Deleting object from a view in Django从Django中的视图中删除对象
【发布时间】:2018-10-23 10:35:25
【问题描述】:

我有一个显示对象列表的页面,我想在每个对象旁边添加一个按钮以使用户能够删除它。我在网上发现了一些关于类似场景的问题,但由于某种原因,我在尝试复制解决方案时不断出错。

这里是views.py中的删除函数:

def delete_dish(request, pk):
    query = Dish.objects.get_object_or_404(pk)
    supermenu = query['supermenu'].pk
    query.delete()
    return redirect('foodmenu:menu', supermenu)

这是 HTML 模板中的表单:

            {% if not supermenu.dish_set.count == 0 %}
            <ul>
            {% for dish in supermenu.dish_set.all %}


                <li>
                {{ dish.name }} - {{ dish.description }}
                <form action="{%  url 'foodmenu:delete_dish' dish.id %}" method="POST">
                    {% csrf_token %}
                    <button type="submit">X</button>
                </form>

                </li>


                    {% if not dish.price_set.count == 0 %}
                    <ul>
                    {% for price in dish.price_set.all %}
                        {% if price.label %}
                            <li>{{ price.label }}: {{ price.cost }}</li>
                        {% else %}
                            <li>{{ price.cost }}</li>
                        {% endif %}
                    {% endfor %}
                    </ul>
                    {% endif %}


                {% endfor %}
            </ul>

            {% else %}
            <p>No dishes on this menu!</p>

        {% endif %}

这里是 urls.py:

app_name = 'foodmenu'
urlpatterns = [
    ...
    path('dish/delete/<int:dish.id>', views.delete_dish, name="delete_dish")
]

当我单击按钮时,浏览器转到 ./dish/delete/1(1 是对象的 pk),但 Django 返回 404 错误。

【问题讨论】:

  • 你确定有pk=1的对象吗?请注意,通常数据库采用最小的未分配整数,它会不断迭代。
  • 只是query = get_object_or_404(pk); query.delete()。因为query 是你的模型。
  • 我不确定。 1 只是从dish.id 返回的数字,它在 HTML 模板中被调用。我对此很陌生,所以我还是有点迷茫。

标签: django django-forms django-urls


【解决方案1】:

你应该使用get_object_or_404 快捷方式而不是query = Dish.objects.get_object_or_404(pk)

from django.shortcuts import get_object_or_404

from django.views.decorators.http import require_POST

@require_POST
def delete_dish(request, pk):
    if request.method
    query = get_object_or_404(Dish, pk=pk)
    supermenu = query.supermenu.pk
    query.delete()
    return redirect('foodmenu:menu', supermenu)

还将您的 url 模式更改为:

path('dish/delete/<int:pk>/', views.delete_dish, name="delete_dish")

UPD

正如@daniherrera 在他的评论中提到的,您可能想要检查请求的方法,以防止意外删除。为此,您可以使用 require_POST 装饰器。

【讨论】:

  • 修正你的答案。删除supermenu = query['supermenu'].pk也可以return redirect('foodmenu:menu', query.pk)
  • query.delete() 之后,查询不存在。这将在这里引发错误return redirect('foodmenu:menu', query.pk)
  • @neverwalkaloner,我的错。当您删除模型时,pk 变为空。不错。
  • @neverwalkaloner,为了避免反模式,检查动作是否是一个好主意是一个 POST:stackoverflow.com/a/46614
  • @neverwalkaloner,可能是使用require_POST()的好机会@
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-14
  • 2016-06-24
  • 1970-01-01
  • 2019-08-03
  • 2013-11-28
  • 1970-01-01
  • 2018-10-17
相关资源
最近更新 更多