Django 使用确认模板和POST方法删除视图

Django 使用确认模板和POST方法删除视图,django,post,confirmation,Django,Post,Confirmation,当我试图使用DeleteView和POST方法同时删除模型的多个对象时,我认为我正在执行一个标准操作,中间有一个确认模板 嗯,要么是我在电脑前坐得太久,要么是Django不直接支持这种所谓的标准方式 正如其他帖子所说,只有在我使用GET方法时才会显示确认模板(带有确认按钮)。但在我的例子中,我有一个ListView,其中包含模型中的所有对象,第一列是复选框,其值对应于相应对象的ID。 我可以一次勾选几个复选框,然后单击我的“删除所选项目”。表单使用POST方法(我不想使用GET) 现在:在使用P

当我试图使用DeleteView和POST方法同时删除模型的多个对象时,我认为我正在执行一个标准操作,中间有一个确认模板

嗯,要么是我在电脑前坐得太久,要么是Django不直接支持这种所谓的标准方式

正如其他帖子所说,只有在我使用GET方法时才会显示确认模板(带有确认按钮)。但在我的例子中,我有一个ListView,其中包含模型中的所有对象,第一列是复选框,其值对应于相应对象的ID。 我可以一次勾选几个复选框,然后单击我的“删除所选项目”。表单使用POST方法(我不想使用GET)

现在:在使用POST方法的情况下,让DeleteView使用确认模板似乎会引起一些麻烦。几个小时后我没有成功

到这里最好的方法是什么

我的类的标题如下所示:

class SomeItemConfirmDeleteView(DeleteView):
    template_name = 'confirm_delete_someitems.html'
    model = SomeItem
    success_url = reverse_lazy('list_someitems_url')
    items_to_delete = []
迄今已采取的步骤:

  • 我重写了POST方法,因此如果我有一个列表,其中包含所有要从复选框中删除的ID,我将调用GET方法,以便显示确认模板。否则,已在Confirm_delete_someitems.html中按下“Confirm deletion”按钮

    def post(self, request, *args, **kwargs):
        self.items_to_delete = self.request.POST.getlist('itemsToDelete')
        if not self.items_to_delete:
            return self.delete(request, *args, **kwargs)
        else:
            return self.get(self, *args, **kwargs)
    
  • 我重写了get_object方法

    def get_object(self, queryset=None):
        return self.get_queryset()
    
  • 我重写了get_queryset方法,以便将要删除的对象显示在confirm_delete_someitems.html的列表中。我从名为“itemsToDelete”的复选框中获取对象

  • 最后一步很棘手:如何从confirm_delete_someitems.html表单中获取要删除的对象:

    <form action="" method="post">
            {% csrf_token %}
            {% trans 'The following objects as well as their related objects will be deleted. Are you sure?' %}
            <ul>
                {% for item in object %}
                    <li>{{ item }}</li>
                {% endfor %}
            </ul>
            <input type="submit" value="{% trans 'Confirm deletion' %}" />
        </form>
    
    
    {%csrf_令牌%}
    {%trans'下列对象及其相关对象将被删除。您确定吗?'%}
    
      {对象%中的项的%s}
    • {{item}}
    • {%endfor%}

    我现在找到了一个解决方案:我基本上添加了隐藏的输入字段,再次传输POST请求中复选框的ID

    但如果有人找到更优雅的方式,我愿意接受建议。:)

    视图.py

    class SomeItemConfirmDeleteView(DeleteView):
        template_name = 'confirm_delete_someitems.html'
        model = SomeItem
        success_url = reverse_lazy('list_someitems_url')
        items_to_delete = []
    
        def get_queryset(self):
            queryset = super(ChargeParkConfirmDeleteView, self).get_queryset()
            self.queryset = queryset.filter(id__in=self.items_to_delete)
            return self.queryset
    
        def get_object(self, queryset=None):
            return self.get_queryset()
    
        def post(self, request, *args, **kwargs):
            self.items_to_delete = self.request.POST.getlist('itemsToDelete')
            if self.request.POST.get("confirm_delete"):
                # when confirmation page has been displayed and confirm button pressed
                queryset = self.get_queryset()
                queryset.delete() # deleting on the queryset is more efficient than on the model object
                return HttpResponseRedirect(self.success_url)
            elif self.request.POST.get("cancel"):
                # when confirmation page has been displayed and cancel button pressed
                return HttpResponseRedirect(self.success_url)
            else:
                # when data is coming from the form which lists all items
                return self.get(self, *args, **kwargs)
    
    class MV_Loeschen(DeleteView):
        template_name = templ_folder_name + 'mv_loeschen.html'
        model = MV
        success_url = reverse_lazy(url_app_name + 'mv_ausgabe_alle')
    
        def get_object(self, queryset=None):
            self.queryset = MV.objects.get(mv_id = self.to_delete)
            return self.queryset
    
        def post(self, request, mvpk):
            self.to_delete = mvpk
            if self.request.POST.get("confirm_delete"):
                queryset = MV.objects.get(mv_id = mvpk)
                queryset.delete()
                return HttpResponseRedirect(self.success_url)
            else:
                return self.get(self, mvpk)
    
    确认\u删除\u某些项目。html:

    <form action="" method="post">
        {% csrf_token %}
        {% trans 'The following objects as well as their related objects will be deleted. Are you sure?' %}
        <ul>
            {% for item in object %}
                <input type="hidden" value="{{ item.id }}" name="itemsToDelete" />
                <li><a href="{{ item.get_absolute_url }}">{{ item }}</a></li>
            {% endfor %}
        </ul>
        <input type="submit" class="btn btn-primary" value="{% trans 'Confirm deletion' %}" name="confirm_delete" />
        <input type="submit" class="btn btn-primary" value="{% trans 'Cancel' %}" name="cancel"/>
    </form>
    
        <form method="post">{% csrf_token %}
                            <div class="form-group">
                                    Sure, you want to delete that object?<br>
                                    <br>
                                    <strong>{{ object }}</strong>
                                    {{ form.errors }}
                                    <br>
                                    <br>
                                    <input type="hidden" name="confirm_delete" value="confirm_delete">
                                    <button type="submit" class="btn btn-primary">Delete</button>
                            </div>
                    </form>
    
    
    {%csrf_令牌%}
    {%trans'下列对象及其相关对象将被删除。您确定吗?'%}
    
      {对象%中的项的%s}
    • {%endfor%}
    谢谢Marc

    这对我真的很有帮助。我还想通过post方法获得一些基于类的通用视图,比如DeleteView。然而,我不得不改变一些事情,如果像我这样对Python了解有限的人会寻找解决方案,我想在这里添加这些内容

    我的html模板的一部分:

    <form action="" method="post">
        {% csrf_token %}
        {% trans 'The following objects as well as their related objects will be deleted. Are you sure?' %}
        <ul>
            {% for item in object %}
                <input type="hidden" value="{{ item.id }}" name="itemsToDelete" />
                <li><a href="{{ item.get_absolute_url }}">{{ item }}</a></li>
            {% endfor %}
        </ul>
        <input type="submit" class="btn btn-primary" value="{% trans 'Confirm deletion' %}" name="confirm_delete" />
        <input type="submit" class="btn btn-primary" value="{% trans 'Cancel' %}" name="cancel"/>
    </form>
    
        <form method="post">{% csrf_token %}
                            <div class="form-group">
                                    Sure, you want to delete that object?<br>
                                    <br>
                                    <strong>{{ object }}</strong>
                                    {{ form.errors }}
                                    <br>
                                    <br>
                                    <input type="hidden" name="confirm_delete" value="confirm_delete">
                                    <button type="submit" class="btn btn-primary">Delete</button>
                            </div>
                    </form>
    
    那么,我在这里干什么?def post()方法向MV_Loeschen解释如何处理post请求。我通过post表单从另一个页面接收到一个参数mvpk,在这里我告诉Django我想转到一个视图,以便删除mvpk中id为的MV对象

    然后我将self.to_delete设置为包含该id(mvpk)。我以后需要另一个def。然后我必须看看我是否刚刚到达确认页面(你真的想删除它吗?),或者我是否已经确认要删除该对象。第一个案例在最后由else fork(或者您如何称呼它)处理。这似乎在内部引发了对DeleteView的调用,但使用了GET方法。所以我查了一下

    https://docs.djangoproject.com/en/3.0/ref/class-based-views/generic-editing/#django.views.generic.edit.DeleteView
    
    还有我的
    python/站点包/子文件夹中的代码

    def get依次使用get_对象方法。但是这个def get_对象不知道mvpk/我的MV对象的id。所以,我从self.to_delete中得到了这个值(因此我需要在之前分配它)。在这里,我采取了与Marc不同的方法

    在他的解决方案中,
    get\u object()
    调用
    get\u queryset()
    ,它返回一个queryset,而我不理解他的解决方案中的超行,我只是直接在
    get\u object()
    中获取queryset

    所以回到def
    post()
    。如果我已经确认要删除该对象,则必须获取该参数。我是这样做的:

    self.request.POST.get("confirm-delete")
    
    再次感谢,马克,我想知道为什么我无法访问:

    request.POST['confirm-delete']
    
    直接的。我不确定我现在是否完全理解了这一点,但至少你帮助我使这项工作得以开展

    然后我可能会有一个带有queryset新设置的冗余行。我不知道。然后我分别删除queryset或MV对象


    最后,我重定向到success\u url,不得不从
    django.http
    导入
    HttpResponseRedirect

    该模板代码是您实际的模板代码吗?我没有看到您提到的复选框。这是confirm\u delete\u someitems.html的模板代码。复选框所在的另一个模板在这里并不重要。