Я пытаюсь написать небольшое приложение, которое получает видеофайлы, и конвертирует их в единый формат после их загрузки (таким образом, добавляется в базу данных). Я искал в Интернете наилучшее решение для этого и решил использовать сигналы Django с Celery. Но пока я пытаюсь создать доказательство концепции, чтобы увидеть, работает ли она.
Я пытаюсь выполнить метод video_repalce()
после того, как новое видео было загружено (таким образом, новая база была добавлена в базу данных). Но сигнал не работает правильно, или я не понимаю, как работает вся система.
Я использую Django 1.2.3 с заранее определенным сигналом django.db.models.signals.post_init
, который должен вызываться после создания модели ( таким образом, новая база была добавлена в базу данных).
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()
.