Django:即使删除被阻止也能获取成功删除的信息

2 投票
2 回答
1711 浏览
提问于 2025-04-17 12:58
class SomeModel(models.Model):
    end = models.DateTimeField()

    def delete(self, *args, **kwargs):
        now = datetime.datetime.now()
        if self.end < now:
            return  # past events cannot be deleted

        super(SomeModel, self).delete(self, *args, **kwargs)

我在我的一个模型里写了上面的代码。

它运行得很好,但有一个小问题:

我收到一条消息,说对象已经成功删除,但实际上这个模型并没有被删除,因为我设置的条件不满足。

有没有办法在这种情况下发送一条消息,告诉我对象没有被删除呢?

注意:这个模型只是用于django-admin。

2 个回答

0

你可以在你重写的delete()函数中返回True或False,然后在你的表单中根据这个值来构建你的消息。

def delete(self, *args, **kwargs):
    now = datetime.datetime.now()
    if self.end < now:
        return False  # past events cannot be deleted

    super(SomeModel, self).delete(self, *args, **kwargs)
    return True #successfully deleted from the database
2

Django后台的删除视图并不会检查delete()调用是否成功,所以如果你想像问题中那样重写删除方法,你需要重写整个ModelAdmin.delete_view方法。

如果SomeModel只在Django后台使用,另一种可能的方法是重写has_delete_permission方法。这样做会从修改视图中移除删除链接,并且禁用过去事件的删除页面。

class SomeModelAdmin(admin.ModelAdmin):
    ...
    def has_delete_permission(self, request, obj=None):
        """
        Return False for events in the past
        """
        if obj is None:
            # obj is None in the model admin changelist view
            return False
        now = datetime.datetime.now()
        if obj.end < now:
            return False # past events cannot be deleted
        else:
            return super(SomeModelAdmin, self).has_delete_permission(request, obj)

上面的实现会禁用“删除选定对象”的后台操作,因为当对象为None时我们返回False。你应该考虑这样做,因为它调用的是查询集的删除方法,而不是你重写的删除方法。

采用这种方法,超级管理员仍然可以删除事件,因为他们拥有所有权限。如果SomeModel出现在模型内联中,我认为这种方法可能不适用——不过我看到在Django 1.4中has_delete_permissionInlineModelAdmin的一个选项。

撰写回答