【问题标题】:Delete object with form in django在 django 中使用表单删除对象
【发布时间】:2018-11-05 21:43:20
【问题描述】:

我正在展示一张桌子。在每一行中都应该有一个删除按钮,用于从表格中删除元素。

我的问题是,我不确定如何将元素的 id 传递给视图。

html:

{% for post in posts %}
    <div>
        <h3>Zuletzt ausgewählt:</h3>
        <p>published: <b>{{ post.pub_date }}</b>
        </p>
        <p>
            name: <b>{{ post.Name }}</b>
            anmeldung: <b>{{ post.get_Anmeldung_display }}</b>
            essen: <b>{{ post.get_Essen_display }}</b>
                <form action="" method="POST">
                  {% csrf_token %}
                  <input class="btn btn-default btn-danger" name="delete" type="submit" value="Löschen"/>
                </form>
        </p>
        <p>
            Email: <b>{{ post.Email }}</b>
        </p>
    </div>
{% endfor %}

views.py

if request.method == 'POST' and 'delete' in request.POST:
    Eintrag.objects.filter(pk=id).delete()
    return HttpResponseRedirect(request.path)  

所以我需要将每个帖子的 post.pub_date 传递给视图,我该如何实现呢?

【问题讨论】:

  • > 所以我需要将每个帖子的 post.pub_date 传递给视图,我该如何实现呢?不,是视图将 post.pub_date 传递给模板,为什么要把它传回去?
  • 嗯,按钮应该知道要删除哪个帖子 - 您将 post.pub_date 传递给按钮是真正的问题
  • 添加一个属性:&lt;input id="{{ post.pk }}" ... /&gt; 和一个 AJAX 调用到视图传递 pk 删除

标签: django


【解决方案1】:

我的问题是,我不确定如何将元素的 id 传递给视图。

我可以想到两种方法来做到这一点。我会一一介绍。

1. 在您的应用中创建一个单独的 url 路由,专门用于删除对象:

('/post/<pk>/delete/', name="delete_post"),

然后将表单的action 指向此网址:

<form action="{% url 'delete_post' post.pk %}" method="POST">
    ...

最后,修改您的视图函数以接受pk 参数:

def my_view(request, pk): 
    ...

2. 第二种方法是在表单中创建另一个字段并将对象的 pk 传递给它:

只需在表单中创建另一个字段。

<form action="" method="POST">
    <input type="hidden" value="{{ post.pk }}" name="pk">
    ...

那么在您看来,只需查看request.POST['pk'] 即可获取帖子的pk。

【讨论】:

  • 感谢您的回答。我喜欢第二个想法,但我得到了一个带有 request.POST['pk'] 的 MultiValueDictKeyError,有什么想法吗?
  • @Sebastian 啊,是的。我忘了在输入字段中添加name="pk" 属性。
【解决方案2】:

一种使用 Django 通用视图非常容易实现的非 ajax 方式是这样的:

模板.html

{% for post in posts %}
<div>
    <h3>Zuletzt ausgewählt:</h3>
    <p>published: <b>{{ post.pub_date }}</b>
    </p>
    <p>
        name: <b>{{ post.Name }}</b>
        anmeldung: <b>{{ post.get_Anmeldung_display }}</b>
        essen: <b>{{ post.get_Essen_display }}</b>
            <form action="" method="POST">
              {% csrf_token %}
              <input class="btn btn-default btn-danger" name="delete" type="submit" value="Löschen"/>
            </form>
    </p>
    <p>
        Email: <b>{{ post.Email }}</b>
    </p>
    <a href="/deleteurl/{{ post.pk }}">
        Delete this!
    </a>
</div>
{% endfor %}

一旦用户点击删除链接,他们将被重定向到删除视图和模板,其中的 URL 类似于“/deleteurl/1/”。

那么您用于处理删除的视图、url 和模板集可能如下所示:

views.py

class DeleteMe(generic.DeleteView):
    template_name = 'deleteconfirmation.html'
    model = YourModel
    success_url = '/YourRedirectUrl/'

urls.py

url(r'^deleteurl/(?P<pk>\d+)/$', 
    views.DeleteMe.as_view(), name='deletemeview'),     

删除确认.html

<form action="" method="post">{% csrf_token %}
    <p>Are you sure you want to delete "{{ object }}"?</p>
    <input type="submit" value="Confirm" />
</form>

同样,这没有使用 Ajax。

视图和模板直接取自Django Docs

【讨论】:

    【解决方案3】:

    使用 POST 是我们的首要任务,但我认为添加另一个表单将是多余的。

    django-allauth'电子邮件视图中找到了解决方案。
    虽然它不包括确认步骤(如在文档中,由@HoneyNutIchiros 或in more details 或通过onclick 提及),但它可能很有用。
    他们将名称 (action_remove) 添加到按钮并在 request.POST 字典中检查:

    # account/email.html
    <button type="submit" name="action_primary" >{% trans 'Make Primary' %}</button>
    <button type="submit" name="action_send" >{% trans 'Re-send Verification' %}</button>
    <button type="submit" name="action_remove" >{% trans 'Remove' %}</button>
    ...
    <button name="action_add" type="submit">{% trans "Add E-mail" %}</button>
    
    # account/views.py
    class EmailView(AjaxCapableProcessFormViewMixin, FormView):
        ...
        def post(self, request, *args, **kwargs):
            ...
            if "action_add" in request.POST:
                res = super(EmailView, self).post(request, *args, **kwargs)
            elif "action_remove" in request.POST:
                res = self._action_remove(request)
            ...
            return res
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      • 1970-01-01
      • 2021-05-28
      • 2017-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多