ビデオファイルを受け取り、アップロードされた後(つまり、データベースに追加された)、一様なフォーマットに変換する小さなアプリケーションを作成しようとしています。私はこのための最良の解決策をWebで検索し、CeleryでDjangoの信号を使用することに決めました。しかし、今のところ私はそれが動作するかどうかを確かめるために概念の証明を作成しようとしています。Django - post_initシグナルは、インスタンスインスタンスが保存される前に、モデルインスタンスsaveで呼び出されます。どうして?
新しいビデオがアップロードされた後(つまり、新しい行がデータベースに追加された後)、video_repalce()
メソッドを実行しようとしています。しかし、信号が正しく機能しない、または私はシステム全体の仕組みが理解できませんでした。
Iは(したがって、新しい行がデータベースに追加された)がshould be called after a model has been instantiated、事前定義された信号django.db.models.signals.post_init
とジャンゴ1.2.3を使用しています。
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は...また、新しいモデルのインスタンスが作成されていないだけと呼ばれているが、:モデルをしてもインスタンス化され
- 前に。つまり、データベースにデータが1行もない(つまり、モデルオブジェクトをインスタンス化する必要はありません)場合、初めてサーバーを実行するときに呼び出されます。インスタンスの
self.pk
はNone
です! save()
- 機種を指定した場合。上記のコードは、私がself.save()
を押すと実行されます。
実際には、ドキュメントに従って動作しません。
私は間違っていますか?これは概念実証であることを忘れないでください。私はそれが働いていることを確認した後にコードをCeleryに移動するつもりです。しかし、信号が正常に機能しない場合、Celeryは助けになりません - 私はsave()
またはビデオを更新する度に、信号は常に数回再送されます。
save()
をreplace_video()
の方法で呼び出すべきではないと思いますか?だから私はそれをどこに呼びますか?どの信号を選ぶべきですか? post_save
は、私がsave()
を押すたびに呼び出されるため、良い選択肢ではありません。
サーバを実行するときにシグナルが常に送信されることを言いますが、シェル 'manage.py shell'を開いてモデルをインポートするとどうなりますか? –