【问题标题】:Within a Django Model, how can I prevent a delete based on a particular field?在 Django 模型中,如何防止基于特定字段的删除?
【发布时间】:2016-07-17 09:45:50
【问题描述】:

在下面,我有一个Post 模型。 Post 对象有一个 status 字段,可以是 'unpublished''published'

if status is 'published',我想防止对象被删除,并希望将这个逻辑封装在模型本身中。

from model_utils import Choices  # from Django-Model-Utils
from model_utils.fields import StatusField


class Post(model.Models)

    STATUS = Choices(
        ('unpublished', _('Unpublished')),
        ('published', _('Published')),
    )

    ...

    status = StatusField(default=STATUS.unpublished)

我该怎么做?如果使用QuerySet 批量删除对象,则覆盖delete 方法将不起作用。我读过不要使用接收器,但我不知道为什么。

【问题讨论】:

  • 当您通过 QuerySet.delete() 删除时,会调用一个预删除事件,因此监听它并引发 ProtectedError 应该可以解决问题。
  • 我在文档中找不到 - 你能指点我吗?我以为那不会发出信号。
  • pre_delete。我正在通过电话写信,如果您以后没有收到,我无法提供完整的答案,我可以尝试提供一个。
  • 谢谢,我已经添加了一个基于此的答案

标签: django django-models overriding receiver


【解决方案1】:

这是我在@Todor 的评论之后得到的:

signals.py:

from django.db.models import ProtectedError
from django.db.models.signals import pre_delete
from django.dispatch import receiver

from .models import Post

@receiver(pre_delete, sender=Post, dispatch_uid='post_pre_delete_signal')
def protect_posts(sender, instance, using, **kwargs):
    if instance.status is 'unpublished': 
        pass
    else:  # Any other status types I add later will also be protected
        raise ProtectedError('Only unpublished posts can be deleted.')

我欢迎改进或更好的答案!

【讨论】:

  • 根据django documentation,我们必须包含受保护的对象,因此应该引发 ProtectedError('Only unpublished posts can be deleted.', instance)
  • 你如何捕捉到ProtectedError?在我的 Django 1.11 上,异常只是冒泡到 500 服务器错误。
  • @psaniko 你有没有找到捕捉ProtectedError的方法?
  • @shadow 不记得了,但我认为我们必须修复错误处理程序或添加中间件来捕获它。一些 SO 问题直接解决了这个问题stackoverflow.com/questions/44229783/…
  • @psaniko 非常感谢您的回复。正如stackoverflow.com/questions/49326282 中所述,我让它覆盖了 delete_view 和 response_action
猜你喜欢
  • 2011-06-17
  • 2018-05-03
  • 2013-01-07
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 1970-01-01
  • 2019-12-30
相关资源
最近更新 更多