Próbuję napisać małą aplikację, która odbiera pliki wideo, i przekonwertować je do jednolitego formatu po ich przesłaniu (w ten sposób dodane do bazy danych). Przeszukałem internet, szukając najlepszego rozwiązania tego problemu, i postanowiłem wykorzystać sygnały Django z Celery. Ale na razie próbuję stworzyć proof-of-concept, aby sprawdzić, czy to działa.Django - sygnał post_init jest wywoływany w momencie zapisu instancji modelu i przed utworzeniem instancji. Czemu?
Próbuję wykonać metodę video_repalce()
po przesłaniu nowego filmu wideo (w ten sposób do bazy danych został dodany nowy wiersz). Ale sygnał nie działa poprawnie lub nie rozumiem, jak działa cały system.
mi stosując Django 1.2.3 wstępnie zdefiniowane sygnału django.db.models.signals.post_init
, który should be called after a model has been instantiated (a więc, nowy rekord został dodany do bazy danych).
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")
Jednak post_init nazywa nie tylko kiedy nowa instancja modelu jest tworzony, ale także ...:
- Przed model jest nawet instancja. Mam na myśli to, że jest wywoływana, gdy pierwszy raz exeucte serwera, gdy nie ma nawet jeden wiersz danych w bazie danych (tak, nie powinny być tworzone instancję obiektów Model). Wersja
self.pk
toNone
! - Po wykonaniu modelu
save()
. Powyższy kod jest również wykonywany po trafieniu naself.save()
.
Praktycznie nie działa zgodnie z dokumentami.
Co robię źle? Pamiętaj, że jest to dowód koncepcji. Zamierzam przenieść kod do Celery po tym, jak widzę, że działa. Ale jeśli sygnały nie działają poprawnie, Celery nie pomoże - sygnał zawsze będzie ponownie wysyłany kilka razy, gdy tylko save()
lub zaktualizuje wideo.
Czy uważasz, że nie powinienem zadzwonić pod numer save()
w metodzie replace_video()
? Więc gdzie mam to nazwać? Który sygnał powinienem wybrać? post_save
nie jest dobrą opcją, ponieważ jest również wywoływana za każdym razem, gdy uderzę save()
.
Wspominasz, że sygnał jest wysyłany zawsze po uruchomieniu serwera, co się stanie, jeśli po prostu otworzysz powłokę 'manage.py shell 'i zaimportujesz model? –