Sto provando a scrivere una piccola applicazione che riceve i file video e li converte in un formato uniforme dopo che sono stati caricati (quindi aggiunti al database). Ho cercato sul web la soluzione migliore e ho deciso di utilizzare i segnali di Django con Celery. Ma per ora sto cercando di creare un proof-of-concept per vedere se funziona.Il segnale Django - post_init viene richiamato su Salva istanza modello e prima ancora viene creata l'istanza. Perché?
Sto provando ad eseguire un metodo video_repalce()
dopo che un nuovo video è stato caricato (quindi, una nuova riga è stata aggiunta al database). Ma il segnale non funziona bene, o non ho capito come funziona l'intero sistema.
sto usando Django 1.2.3 con pre-definiti segnale django.db.models.signals.post_init
, che should be called after a model has been instantiated (quindi, una nuova riga è stato aggiunto al database).
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")
Tuttavia, post_init si chiama non solo quando viene creata una nuova istanza modello, ma anche ...:
- Prima che il modello è anche un'istanza. Ciò che intendo è che viene chiamato quando esco dal server per la prima volta, quando non c'è nemmeno una singola riga di dati nel database (quindi, nessun oggetto Modello dovrebbe essere istanziato). L'istanza
self.pk
èNone
! - Quando
save()
-ing un modello. Il codice sopra viene anche eseguito quando ho colpitoself.save()
.
Praticamente, non funziona secondo i documenti.
Cosa sto sbagliando? Ricorda che questa è una dimostrazione di concetto. Intendo spostare il codice su Celery dopo averlo visto funzionare. Ma, se i segnali non funzionano correttamente, Celery non sarà di aiuto - Il segnale verrà sempre inviato nuovamente un paio di volte ogni volta che I save()
o aggiorno un video.
Pensi che non dovrei chiamare save()
nel metodo replace_video()
? Quindi dove dovrei chiamarlo? Quale segnale dovrei scegliere? post_save
non è una buona opzione perché viene anche chiamato ogni volta che colpisco save()
.
Si dice che il segnale viene sempre inviato quando si esegue il server, cosa succede se si apre solo una shell 'shell manage.py' e si importa il modello? –