Django - сигнал post_init вызывается при сохранении экземпляра модели и перед экземпляром даже создается. Почему?

Я пытаюсь написать небольшое приложение, которое принимает видеофайлы и конвертирует их в единый формат после того, как они были загружены (таким образом добавлены в базу данных). Я поискал в Интернете лучшее решение для этого и решил использовать сигналы Django с Celery . Но пока я пытаюсь создать доказательство концепции, чтобы посмотреть, работает ли она.

I ' m пытается выполнить метод 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 вызывается не только при создании нового экземпляра модели, но также ...:

  1. Прежде, чем модель будет даже создана. Я имею в виду, что он вызывается, когда я запускаю сервер в первый раз, когда в базе данных нет ни одной строки данных (таким образом, объекты модели не должны создаваться). self.pk экземпляра равен Нет !
  2. Когда save () -ing модель. Приведенный выше код также выполняется, когда я нажимаю self.save () .

Фактически, он не работает в соответствии с документацией.

Что я делаю не так? Помните, что это проверка концепции. Я собираюсь переместить код на Celery после того, как увижу, что он работает. Но, если сигналы работают неправильно, Celery не поможет - сигнал всегда будет повторно посылаться пару раз, когда я save () или обновляю видео.

Как вы думаете, мне не следует вызывать save () внутри метода replace_video () ? Так как я должен это назвать? Какой сигнал выбрать? post_save не лучший вариант, потому что он ' s также вызывается всякий раз, когда я нажимаю save () .

11
задан Ory Band 15 January 2011 в 14:55
поделиться