Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Django模型中,如何防止基于特定字段的删除?_Django_Django Models_Overriding_Receiver - Fatal编程技术网

在Django模型中,如何防止基于特定字段的删除?

在Django模型中,如何防止基于特定字段的删除?,django,django-models,overriding,receiver,Django,Django Models,Overriding,Receiver,在下面,我有一个Post模型。Post对象有一个status字段,该字段可以是'unpublished'或'published' 如果状态为“已发布”,我希望防止删除该对象,并希望将该逻辑封装在模型本身中 from model_utils import Choices # from Django-Model-Utils from model_utils.fields import StatusField class Post(model.Models) STATUS = Choi

在下面,我有一个
Post
模型。
Post
对象有一个
status
字段,该字段可以是
'unpublished'
'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
方法将不起作用。我读过《不要使用接收器》,但我不知道为什么。

以下是@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.')

我欢迎改进或更好的答案

当您通过QuerySet.delete()删除时,会调用一个预删除事件,因此监听它并引发ProtectedError应该可以解决问题。我在文档中找不到它-请您给我指出这个问题好吗?我以为那不会发出信号。。我正在通过电话写信,无法提供完整答案,如果您稍后无法获得答案,我可以尝试提供一个答案。谢谢,我已基于此添加了一个答案,因为我们必须包含受保护的对象,因此它应该是raise ProtectedError(“只有未发布的帖子才能删除”,例如)如何捕获
保护错误
?在我的Django 1.11上,异常只会冒泡到500服务器错误。