3

I'm trying to override the delete method for a model named Invoice. Model Invoice is referenced by ForeignKey in model Action. I want to update a BooleanField named billed in model Admin when it's Invoice is deleted

the solution described in this post:

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

that answer: https://stackoverflow.com/a/1539182

is not working for me like this in models.py:

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

also tried:

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()

The ForeignKey Field in Model Action has a on_delete=models.SET_NULL to avoid to delete actions when the invoice is deleted. But I also need to set billed back to False.

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

I just read here https://code.djangoproject.com/ticket/10751 that in Admin the action delete selected could not be overridde with delete()

I have to use delete_view() instead

So I tried

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)

Also tried to use obj instead of self, but not the solution

Community
  • 1
  • 1
surfi
  • 1,451
  • 2
  • 12
  • 25
  • When you say, "not working" what do you mean, are the Action objects not being updated or are the Invoice objects not being deleted or both? Are you throwing an error? – scoopseven May 30 '12 at 15:37
  • The Invoices being updated (deleted), but nothings happend to the Actions. The action delete() or delete_selected() were not overridden. Now it works with get_actions and del deleted_selected and pass than a custom action delete_model to the model. – surfi May 31 '12 at 09:43

2 Answers2

8

While this answer works, if you delete a single obj anywhere else in your code, the delete_model method will throw an error.

I recommend this:

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. :)

Community
  • 1
  • 1
sethwhite
  • 286
  • 3
  • 11
7

I HAVE FOUND A SOLUTION, postet y Stephane https://stackoverflow.com/a/4534773/326905 and edited it for my issue.

The correct action is delete_selected In admin.py under the InvoiceAdmin Model

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'
Community
  • 1
  • 1
surfi
  • 1,451
  • 2
  • 12
  • 25