在Django中覆盖QuerySet.delete() [英] Overriding QuerySet.delete() in Django

查看:460
本文介绍了在Django中覆盖QuerySet.delete()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Django模型,可以将应用程序的功能设置为核心。您不应该删除此模型。我试图强制这个应用程序范围。我已经禁用了admin中的删除功能,并且还禁用了模型上的delete方法,但是QuerySet有自己的delete方法。示例:

  MyModel.objects.all()[0] .delete()#覆盖,不执行任何

MyModel.objects.all()。delete()#POOF!讽刺的是,Django文档说有这样的说法是为什么delete()是QuerySet的一个方法,不是经理:


这是一种安全机制,可以防止您意外请求Entry.objects.delete(),并删除所有条目。


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



任何人都有一个线索,如何在某个东西作为核心覆盖此方法作为QuerySet没有猴子修补源?

解决方案

您可以覆盖经理的默认值 QuerySet 通过覆盖 Manager.get_query_set()方法。



示例: h3>

  class MyQuerySet(models.query.QuerySet):

def delete(self):
pass#你可以抛出一个异常


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() 将不执行任何操作。



有关更多信息:修改初始管理器QuerySets


I have a Django model that holds settings core to the function of an app. You should never delete this model. I'm trying to enforce this application-wide. I've disabled the delete function in the admin, and also disabled the delete method on the model, but QuerySet has it's own delete method. Example:

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

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

Ironically, the Django docs say has this to say about why delete() is a method on QuerySet and not Manager:

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

How having to include .all() is a "safety mechanism" is questionable to say the least. Instead, this effectively creates a backdoor that can't be closed by conventional means (overriding the manager).

Anyone have a clue how to override this method on something as core as QuerySet without monkey-patching the source?

解决方案

You can override a Manager's default QuerySet by overriding the Manager.get_query_set() method.

Example:

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

Now, MyModel.objects.all().delete() will do nothing.

For more informations: Modifying initial Manager QuerySets

这篇关于在Django中覆盖QuerySet.delete()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆