'How to abort model instance deletion from django model admin interface based on some condition

I want to abort model deletion from django admin based on some condition.

I tried overriding delete_queryset(self, request, queryset) method.

class MyModelAdmin(ModelAdmin):
    def delete_queryset(self, request, queryset):
        if not MyModel.objects.filter(is_active=True).exists():
            message = "Error message"
            raise ValidationError(message)
        super().delete_queryset(request, queryset)

This doesn't work since django does not handles exception at this stage.

Found this in Django documentation: https://docs.djangoproject.com/en/4.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_deleted_objects

But I am not sure how can I redirect from here to Django admin page where all model instances are listed and display the error message to user.



Solution 1:[1]

You can override the .has_delete_permission(…) method [Django-doc]:

class MyModelAdmin(ModelAdmin):
    # …
    
    def has_delete_permission(self, request, obj=None):
        if (my_condition):
            return False
        return super().has_delete_permission(request, obj)

Here obj is the object that will be removed. For example if you want to prevent removing an object with is_active is True, you can work with:

class MyModelAdmin(ModelAdmin):
    # …
    
    def has_delete_permission(self, request, obj=None):
        if obj is not None and obj.is_active:
            return False
        return super().has_delete_permission(request, obj)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1