我正在尝试覆盖名为Invoice的模型的delete方法。 Model Invoice在模型Action中由ForeignKey引用。我想更新名为“模拟管理员”的布尔字段,当它的“发票被删除”
时这篇文章中描述的解决方案:
How do I override delete() on a model and have it still work with related deletes
答案是: https://stackoverflow.com/a/1539182 在model.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,以避免在删除发票时删除操作。但我还需要将结账设置为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,但不是解决方案
答案 0 :(得分:7)
我找到了一个解决方案,发表了Stephane https://stackoverflow.com/a/4534773/326905,并根据我的问题对其进行了编辑。
正确的操作是 delete_selected 在InvoiceAdmin模型下的 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'
答案 1 :(得分:7)
虽然this answer有效,但如果您在代码中的任何其他地方删除了一个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'
只需覆盖“更改列表”管理页面的delete_selected
操作即可。这样您就不必完全删除操作,覆盖delete_model
方法,而且您还可以从更改<object>
管理页面中删除单个项目。从长远来看,它的代码较少。 :)