Ich versuche, eine kleine Anwendung zu schreiben, die Videodateien empfängt und sie in ein einheitliches Format konvertiert, nachdem sie hochgeladen wurden (also der Datenbank hinzugefügt). Ich habe im Internet nach der besten Lösung dafür gesucht und mich entschieden, Djangos Signale mit Celery zu verwenden. Aber jetzt versuche ich einen Proof-of-Concept zu erstellen, um zu sehen, ob es funktioniert.Django - post_init-Signal wird an Model-Instanz aufgerufen. Save & before-Instanz wird sogar erstellt. Warum?
Ich versuche, eine video_repalce()
Methode auszuführen, nachdem ein neues Video hochgeladen wurde (daher wurde eine neue Zeile zur Datenbank hinzugefügt). Aber das Signal funktioniert nicht richtig, oder ich habe nicht verstanden, wie das ganze System funktioniert.
Ich verwende Django 1.2.3 mit vordefinierten Signal django.db.models.signals.post_init
, die should be called after a model has been instantiated (So wurde eine neue Zeile in die Datenbank hinzugefügt).
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")
jedoch post_init wird genannt nicht nur wenn ein neues Modell Instanz erstellt wird, aber auch ...:
- Bevor das Modell selbst instanziiert wird. Was ich meine ist, es heißt, wenn ich den Server zum ersten Mal execute, wenn es nicht einmal eine einzige Reihe von Daten in der Datenbank gibt (also sollten keine Model-Objekte instanziiert werden). Die Instanz
self.pk
istNone
! - Wenn
save()
-ein Modell. Der obige Code wird auch ausgeführt, wenn ichself.save()
drücke.
Praktisch funktioniert es nicht gemäß den Dokumenten.
Was mache ich falsch? Denken Sie daran, dass dies ein Proof-of-Concept ist. Ich beabsichtige, den Code zu Celery zu verschieben, nachdem ich sehe, dass es funktioniert. Aber, wenn die Signale nicht richtig funktionieren, Celery wird nicht helfen - Das Signal wird immer ein paar Mal erneut gesendet werden, wenn ich save()
oder ein Video aktualisieren.
Glaubst du, ich sollte nicht save()
innerhalb der replace_video()
Methode anrufen? Also, wo soll ich es nennen? Welches Signal sollte ich wählen? post_save
ist keine gute Option, weil es auch aufgerufen wird, wenn ich save()
treffe.
Sie erwähnen, dass das Signal immer gesendet wird, wenn Sie den Server ausführen, was passiert, wenn Sie nur eine Shell 'manage.py shell' öffnen und das Modell importieren? –