【问题标题】:Override delete_selected() and update fields of child model覆盖 delete_selected() 并更新子模型的字段
【发布时间】:2012-05-30 11:02:53
【问题描述】:

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

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

How do I override delete() on a model and have it still work with related deletes

那个答案: 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 在 Admin 中选择的操作删除不能被 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,但不是解决办法

【问题讨论】:

  • 当您说“不工作”时,您的意思是,Action 对象没有被更新还是 Invoice 对象没有被删除,或者两者兼而有之?你是不是报错了?
  • 发票正在更新(删除),但操作没有发生任何事情。操作 delete() 或 delete_selected() 未被覆盖。现在它可以与 get_actions 和 del deleted_selected 一起使用,并将自定义操作 delete_model 传递给模型。

标签: django model


【解决方案1】:

虽然this answer 有效,但如果您在代码中的其他任何位置删除单个objdelete_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 方法,而且,您仍然可以从 Change <object> 管理页面中删除单个项目。从长远来看,它的代码更少。 :)

【讨论】:

    【解决方案2】:

    我找到了一个解决方案,postet y 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'
    

    【讨论】:

    • 通过编辑画面删除该模型时会报错。
    猜你喜欢
    • 2013-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 1970-01-01
    • 2012-02-14
    • 2014-06-01
    • 2022-12-06
    相关资源
    最近更新 更多