我有一个Django模型,它将设置核心保存到应用程序的功能中.你永远不应该删除这个模型.我正在尝试强制执行此应用程序.我在管理员中禁用了删除功能,并且还禁用了模型上的删除方法,但QuerySet有自己的删除方法.例:
MyModel.objects.all()[0].delete() # Overridden, does nothing
MyModel.objects.all().delete() # POOF!
Run Code Online (Sandbox Code Playgroud)
具有讽刺意味的是,Django文档说这有关于为什么delete()是QuerySet上的方法而不是Manager的原因:
这是一种安全机制,可以防止您意外地请求Entry.objects.delete(),并删除所有条目.
如何包括.all()"安全机制"至少可以说是有问题的.相反,这有效地创建了一个无法通过传统方式关闭的后门(覆盖管理器).
任何人都有一个线索如何在没有猴子修补源的情况下在像QuerySet这样的核心上覆盖这个方法?
man*_*nji 45
您可以通过覆盖方法来覆盖Manager's默认值.QuerySetManager.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()
Run Code Online (Sandbox Code Playgroud)
现在,MyModel.objects.all().delete()什么都不做.
有关更多信息:修改初始Manager QuerySet
https://gist.github.com/dnozay/373571d8a276e6b2af1a
使用@manji发布的类似食谱,
class DeactivateQuerySet(models.query.QuerySet):
'''
QuerySet whose delete() does not delete items, but instead marks the
rows as not active, and updates the timestamps
'''
def delete(self):
self.deactivate()
def deactivate(self):
deleted = now()
self.update(active=False, deleted=deleted)
def active(self):
return self.filter(active=True)
class DeactivateManager(models.Manager):
'''
Manager that returns a DeactivateQuerySet,
to prevent object deletion.
'''
def get_query_set(self):
return DeactivateQuerySet(self.model, using=self._db)
def active(self):
return self.get_query_set().active()
Run Code Online (Sandbox Code Playgroud)
并创建一个mixin:
class DeactivateMixin(models.Model):
'''
abstract class for models whose rows should not be deleted but
items should be 'deactivated' instead.
note: needs to be the first abstract class for the default objects
manager to be replaced on the subclass.
'''
active = models.BooleanField(default=True, editable=False, db_index=True)
deleted = models.DateTimeField(default=None, editable=False, null=True)
objects = DeactivateManager()
class Meta:
abstract = True
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10767 次 |
| 最近记录: |