如何取消 django 信号中的删除
有没有办法使用 django pre_delete 信号取消记录删除?
示例:
def on_delete(sender,**kwargs):
if not <some condition>:
#cancel the deletion
# else continue with the deletion
pre_delete.connect(on_delete,sender=MyModel)
另一个问题是有没有办法对模型说“在更改文件之前先删除原始文件”,因为现在这就是我所做的(参见下面的代码)并且我不确定这是否是最好的方法。
def on_save(sender,**kwargs):
obj = kwargs['instance']
try:
id = obj.pk
# find the file
original_file = sender.objects.get(pk=id)
# delete the original file before uploading a new file
original_file.file.delete()
except ....
pre_save.connect(on_save,sender=ModelWithFileUpload)
(在 django 1.2 中,他们在更改或删除时自动删除文件,但在 django 1.3 中,他们删除了此功能)
提前致谢
Is there a way to cancel a deletion of record using django pre_delete signal?
example:
def on_delete(sender,**kwargs):
if not <some condition>:
#cancel the deletion
# else continue with the deletion
pre_delete.connect(on_delete,sender=MyModel)
and another question is there a way to say to a model "that before changing a file delete first the original file" because right now this is what I do(see code below) and I'm not sure if this is the best way to do it.
def on_save(sender,**kwargs):
obj = kwargs['instance']
try:
id = obj.pk
# find the file
original_file = sender.objects.get(pk=id)
# delete the original file before uploading a new file
original_file.file.delete()
except ....
pre_save.connect(on_save,sender=ModelWithFileUpload)
(in django 1.2 they automatically delete the file on change or on delete but in django 1.3 they removed this feature)
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用内置 Django 信号时这是不可能的。信号上的“send()”和“send_robust()”方法返回一个二元组列表——(接收者,响应)。因此,如果您有正确的代码来处理来自每个接收器的响应,则您可能可以根据一个信号处理程序的返回值来阻止某些操作。
contrib.comments 应用程序执行此操作,允许任何返回 False 的接收器“取消”信号操作。请参阅 第 111-120 行:
但是, 核心 Django 代码 没有任何这种特殊处理。所有这些信号的作用就是通知接收者发生了一些事情。
This is not be possible when using the built-in Django signals. The "send()" and "send_robust()" methods on signals return a list of 2-tuples -- (receiver, response). So, if you have the proper code to handle the responses from each receiver, it is possible that you could prevent some action based on the return value of one signal handler.
The contrib.comments app does this, allowing any receiver which returns False to "cancel" a signal action. See lines 111-120:
However, the core Django code which issues the pre_delete, pre_save, etc signals, does not have any of this special handling. All those signals do is notify the receivers that something has happened.
我会尝试一些黑客解决方法:
并且视图
在信号中引发异常应该制动delete()方法执行,同时将异常返回到调用它的地方。您可以创建自己的 Exception 子类来仅排除某些类型的异常(您几乎永远不应该使用不带参数的 except)。
I would try a little hack workaround:
and the view
Raising exception in signal should brake delete() method execution while returning exception to the place it was invoked. You could create your own Exception subclass to except only certain type of exception (you almost never should use except with no args).
我知道我的回答有点晚了,但这个问题的第二部分正是我几天前所需要的。
所以,首先要做的事情是:
不是真的,除了 dk 提出的那个。老实说,不应该有任何。为什么?因为 pre_delete 意味着在删除对象之前发生的操作。如果你阻止删除,它就不再是pre_delete(注意到恶性循环了吗?)
是的,有,而且你说得非常正确。我创建了一个更通用的代码,它将适用于任何具有关联的 File 对象的模型(见下文)。但是,您应该正手 阅读为什么此行为在 Django 1.3 中被删除,并查看它是否以任何方式影响您的逻辑。它主要与您如何处理回滚以及不同模型对同一文件的多次引用有关。
请记住,这假设您的删除/更新操作将会成功。如果失败,您将永久丢失文件。
更好的方法是在 post_save/post_delete 信号中处理文件删除,或者创建一个 cron 作业来定期清理数据库中不再引用的所有文件。
I know my answer comes a bit late, but the second part of this question is exactly what I needed a few days ago.
So, first things first:
Not really, except for the one proposed by thedk. And honestly, there shouldn't be any. Why? Because pre_delete is meant for an action that is suppose to happen before deleting an object. If you prevent the deletion, it is no longer pre_delete (notice the vicious circle?)
Yes, there is, and you got it pretty much right. I created a more generic code, which will work for any model which has File objects associated (see below). However, you should forehand read why this behaviour was removed in Django 1.3 and see if it affects your logic in any way. It is mainly related to how you handle rollbacks and multiple references to the same file from different models.
Please bear in mind that this assumes that your delete/update action will be successful. In case it fails, you have permanently lost a file.
A better approach would be to handle file deletion in the post_save/post_delete signals, or to create a cron job which periodically cleans up all files which are no longer referenced from the database.