覆盖delete_selected()并更新子模型的字段

sur*_*rfi 3 django model

我正在尝试覆盖名为Invoice的模型的delete方法.Model Invoice在模型Action中由ForeignKey引用.我想在删除Invoice时更新名为模型Admin的BillingField

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

如何覆盖模型上的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()
Run Code Online (Sandbox Code Playgroud)

还尝试过:

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()
Run Code Online (Sandbox Code Playgroud)

模型操作中的ForeignKey字段具有on_delete = models.SET_NULL,以避免在删除发票时删除操作.但是我还需要将结账设置为False.

invoice = models.ForeignKey( Invoice, verbose_name = 'Rechnung', null=True, blank=True,on_delete=models.SET_NULL)
Run Code Online (Sandbox Code Playgroud)

我刚刚在这里阅读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)
Run Code Online (Sandbox Code Playgroud)

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

sur*_*rfi 7

我找到了一个解决方案,发布了Stephane /sf/answers/317434141/并为我的问题编辑了它.

正确的动作是delete_selectedadmin.py的InvoiceAdmin模式下

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'
Run Code Online (Sandbox Code Playgroud)


set*_*ite 7

虽然这个答案有效,但如果删除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'
Run Code Online (Sandbox Code Playgroud)

只需覆盖" delete_selected更改列表"管理页面的操作即可.这样您就不必完全删除操作,覆盖delete_model方法,而且您仍然可以从"更改" <object>管理页面中删除单个项目.从长远来看,它的代码更少.:)