Für zukünftige Referenzen: Ich hatte gerade den Fall, dass ich nicht temporäre Dateien für Downloads verwenden könnte. Aber ich musste sie immer noch löschen; also hier ist, wie ich es gemacht habe (ich wollte mich wirklich nicht auf Cron Jobs oder Sellerie oder Wossnamen verlassen, es ist ein sehr kleines System und ich wollte, dass es so bleibt).
def plug_cleaning_into_stream(stream, filename):
try:
closer = getattr(stream, 'close')
#define a new function that still uses the old one
def new_closer():
closer()
os.remove(filename)
#any cleaning you need added as well
#substitute it to the old close() function
setattr(stream, 'close', new_closer)
except:
raise
und dann nahm ich einfach den Stream für die Antwort verwendet und in ihn eingesteckt.
def send_file(request, filename):
with io.open(filename, 'rb') as ready_file:
plug_cleaning_into_stream(ready_file, filename)
response = HttpResponse(ready_file.read(), content_type='application/force-download')
# here all the rest of the heards settings
# ...
return response
Ich weiß, das ist schnell und schmutzig, aber es funktioniert. Ich bezweifle, dass es für einen Server mit Tausenden von Anfragen pro Sekunde produktiv wäre, aber das ist hier nicht der Fall (max ein paar Dutzend pro Minute).
EDIT: vergessen zu präzisieren, dass ich es mit sehr sehr großen Dateien zu tun hatte, die nicht in den Speicher während des Downloads passen konnten. Deshalb verwende ich eine BufferedReader
(was ist unter io.open()
)
'Temporäre Datei sollte gelöscht werden, sobald das Newfile-Objekt entfernt wird': Gibt es einen eingebauten Mechanismus zum automatischen Löschen von' NamedTemporaryFile'-Instanzen? –
Wenn ich richtig bin, werden Objekte vom Garbage Collector zerstört, sobald alle Referenzen darauf zerstört sind. Wenn Sie die Funktion send_file verlassen, sollte kein Verweis mehr auf das newfile-Objekt vorhanden sein. Daher könnte es beim nächsten Ausführen des GC entfernt werden. Der Destruktor von NamedTemporaryFile heißt es: def close (self): wenn nicht self.close_called: self.close_called = True self.file.close() self.unlink (self.name) def __del __ (Selbst): self.close() – fylb
fylb, Sie haben Recht, aber es ist nicht garantiert, dass das Objekt Müll-gesammelt und seine __del__ Methode aufgerufen wird. Wer weiß, was der Müllsammler tun wird? Besser regelmäßig manuell aufräumen. – loevborg