pholz
pholz

Reputation: 714

In Django admin, how to prevent deletion of last object of a type

Is there a way I can prevent the user from deleting the last object of a certain type (i.e. the last row in the table)? They should still be able to delete that kind of object generally, but it must be ensured that there's always at least one entry left - in this particular case, at least one entry associated with the user.

I tried overriding the model's delete function:

def delete(self, *args, **kwargs):
    others = Presentation.objects.filter(user=self.user).exclude(pk=self.pk)
    if len(others) < 1:
        pass
    else:
        super(Presentation, self).delete(*args, **kwargs)

This works, but the user is told that the deletion was actually successful. I'd rather like an error message to be displayed, like when validation fails. Validation only applies to saving, however, as far as I can tell.

Upvotes: 1

Views: 2210

Answers (2)

dan-klasson
dan-klasson

Reputation: 14180

Can you try this too please?

# admin.py
class MyModelAdmin(admin.ModelAdmin):
    def delete_model(self, request, obj):
         if last_record:
              storage = messages.get_messages(request)
              storage.used = True
              messages.error(request, 'Cannot delete last record.')
         else:
              obj.delete()

Another option could be to hide the success message div or span with jQuery.

Upvotes: 2

jgsogo
jgsogo

Reputation: 726

I would suggest you another approach:

1) Create and connect a signal to pre_delete and raise and exception on your condition:

def on_delete(sender,**kwargs):
    if <condition>:
        raise Exception('Abort delete')
    #else: continue and delete

pre_delete.connect(on_delete,sender=Presentation)

2) Then, on the view, you can catch this exception

# view code...
try:
    object.delete()
except:
    # add the desired info to context

Anyway, you can also override model::delete to throw the exception and catch it in the view code.

Upvotes: 1

Related Questions