我正在尝试编写一个接收视频文件的小应用程序,并在上传后将它们转换为统一格式(因此添加到数据库中)。我已经在网上搜索了最佳解决方案,并决定使用Django的信号Celery。但是现在我正试图创建一个概念验证,看看它是否有效。
我正在尝试在上传新视频后执行video_repalce()
方法(因此,新行已添加到数据库中)。但是信号不能正常工作,或者我不明白整个系统是如何工作的。
我正在使用带有预定义信号django.db.models.signals.post_init
的 Django 1.2.3 ,should be called after a model has been instantiated(因此,新行被添加到数据库中)。
from django.core.files.base import File
from django.db.models.signals import post_init
import os
import os.path
import subprocess
class Project(models.Model):
video = models.FileField(upload_to="projects/videos")
def replace_video(self):
"""Replace original video with an updated one."""
# Video conversion process code goes here,
# resulting in a new external video file.
self.video.delete() # Delete the original video.
self.video.save("newfile.webm", File(open("path/to/newfile.webm") ,"wb"))) # Save the new video instead.
self.save() # Commit everything to database.
os.remove("path/to/newfile.webm") # Remove original video copy after it was commited (copied) into the DB.
# ...
# ...
def handle_new_project(sender, **kwargs):
"""Handels some additional tasks for a new added project. i.e. convert video to uniform format."""
project = kwargs['instance']
project.replace_video()
# Call 'Project.replace_video()' every time a new project is added.
post_init.connect(handle_new_project, sender=Project, dispatch_uid="new_project_added")
但是,在创建新模型实例时,post_init不仅称为 ,而且还是......:
self.pk
为None
!save()
- 模型时。当我点击self.save()
。实际上,它根据文档不起作用。
我做错了什么?请记住,这是一个概念验证。我打算在看到它正常工作后将代码移到Celery。但是,如果信号无法正常工作,Celery将无济于事 - 每当我save()
或更新视频时,信号都会重复发送几次。
您认为我不应该在save()
方法中调用replace_video()
吗?那我应该在哪里打电话呢?我应该选择哪个信号? post_save
不是一个好的选择,因为只要我点击save()
,它就会被调用。
答案 0 :(得分:13)
您似乎对实例化对象意味着什么感到困惑。它与数据库没有任何关系。这会实例化一个模型对象而不将其保存到数据库中,在这种情况下,它的pk将为None:
MyObject(field1='foo', field2='bar')
并且(间接地)通过从数据库中获取对象来实例化它:
MyObject.objects.get(field1='baz')
post_init
信号将在这两种情况下发送,即使它们都与保存到数据库无关。
如果您希望在保存时发生某些事情,请覆盖save
方法本身,或使用pre_save
或post_save
信号。您可以通过验证其pk
是否为无来检查该对象之前是否已保存。
答案 1 :(得分:0)
我知道这个问题很老,但我有一个类似的问题,简单的解决方案就是使用 post_save 信号并检查是否创建
@receiver(post_save, sender=YourSender)
def when_init(sender, instance, created, **kwargs):
if created:
...