3

我正在尝试覆盖名为 Invoice 的模型的删除方法。Model Invoice 由模型 Action 中的 ForeignKey 引用。我想在删除发票时更新模型管理员中名为 billed 的 BooleanField

这篇文章中描述的解决方案:

如何覆盖模型上的 delete() 并让它仍然与相关的删除一起使用

那个答案: https ://stackoverflow.com/a/1539182

在models.py中对我不起作用:

def delete(self):
      Action.objects.filter(invoice=self).update(billed=False) # and tried 0 instead of False
      super(Invoice,self).delete()

也试过:

def delete(self):
     actions = Action.objects.filter(invoice=self)
     for action in actions:
        action.billed=False   # and tried 0 instead of False
        action.save()
     super(Invoice,self).delete()

模型操作中的 ForeignKey 字段有一个 on_delete=models.SET_NULL 以避免在删除发票时删除操作。但我还需要将 billed 设置回 False。

invoice = models.ForeignKey( Invoice, verbose_name = 'Rechnung', null=True, blank=True,on_delete=models.SET_NULL)

我刚刚在这里读到https://code.djangoproject.com/ticket/10751在管理员中,选择的操作删除不能被 delete() 覆盖

我必须改用 delete_view()

所以我尝试了

def delete_selected(self, request, obj, extra_context=None):
    Action.objects.filter(invoice=self).update(billed=False)
    super(InvoiceAdmin, self).delete_view(request, obj, extra_context)

也尝试使用obj而不是self,但不是解决方案

4

2 回答 2

8

虽然此答案obj有效,但如果您在代码中的其他任何位置删除单个,该delete_model方法将引发错误。

我推荐这个:

actions = ['delete_selected']

def delete_selected(self, request, obj):
    for o in obj.all():
        Action.objects.filter(invoice=o).update(billed=False)
        o.delete()

delete_selected.short_description = 'Ausgewählte Rechnungen löschen'

Just override the delete_selected action for the Change List admin page. This way you're not having to completely delete the action, override the delete_model method, and as a plus, you can still delete individual items from the Change <object> admin page. In the long run it's less code. :)

于 2014-09-16T16:10:13.393 回答
7

我找到了一个解决方案,postet y Stephane https://stackoverflow.com/a/4534773/326905并针对我的问题对其进行了编辑。

正确的操作是delete_selectedInvoiceAdmin模型下的 admin.py

actions = ['delete_model']

def get_actions(self, request):
    actions = super(InvoiceAdmin, self).get_actions(request)
    del actions['delete_selected']
    return actions

def delete_model(self, request, obj):
    for o in obj.all():
        Action.objects.filter(invoice=o).update(billed=False)
        o.delete()

delete_model.short_description = 'Ausgewählte Rechnungen löschen'
于 2012-06-27T11:03:38.147 回答