django - 在 Django 中覆盖 QuerySet.delete()

标签 django

我有一个 Django 模型,它包含应用程序功能的核心设置。你永远不应该删除这个模型。我正在尝试在整个应用程序范围内强制执行此操作。我在管理员中禁用了删除功能,也禁用了模型上的删除方法,但 QuerySet 有它自己的删除方法。例子:

MyModel.objects.all()[0].delete() # Overridden, does nothing

MyModel.objects.all().delete() # POOF!

具有讽刺意味的是,Django 文档说为什么 delete() 是 QuerySet 上的一个方法而不是 Manager:

This is a safety mechanism to prevent you from accidentally requesting Entry.objects.delete(), and deleting all the entries.



如何必须包含 .all()至少可以说是“安全机制”是值得怀疑的。相反,这有效地创建了一个无法通过常规方式(覆盖管理器)关闭的后门。

任何人都知道如何在像 QuerySet 这样核心的东西上覆盖这个方法而不用猴子修补源?

最佳答案

您可以覆盖 Manager's默认 QuerySet通过覆盖 Manager.get_query_set()方法。
例子:

class MyQuerySet(models.query.QuerySet):

    def delete(self):
        pass  # you can throw an exception


class NoDeleteManager(models.Manager):
    def get_query_set(self):
        return MyQuerySet(self.model, using=self._db)

class MyModel(models.Model)
    field1 = ..
    field2 = ..


    objects = NoDeleteManager()
现在,MyModel.objects.all().delete()什么也不做。
更多信息:Modifying initial Manager QuerySets

关于django - 在 Django 中覆盖 QuerySet.delete(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6459616/

相关文章:

django - 如何在Django中创建静态目录

python - Django + Google 联合登录

ruby-on-rails - Lift 框架是 "easy"还是 Ruby on Rails 或 Django?

python - 用于外键的 Django refresh_from_db

javascript - 切换功能不工作 div 元素不出现

python - 如何更新 Django 的 FileField 实例的文件名?

python - 使用请求数据覆盖序列化程序,包括缺少键的空值

python - 如何使用 Humanize 在 Django 中显示 "This many months ago"?

django - 重置 Django 迁移 : relation "django_migrations" does not exist

django - 在 Django 中对缓存和 django-channels channel 层使用相同的 Redis 存储是否可以?