Ich verwende 1.2.5 mit einem Standard-ImageField und verwende das integrierte Speicher-Backend. Das Hochladen von Dateien ist in Ordnung, aber wenn ich einen Eintrag vom Administrator entferne, wird die eigentliche Datei auf dem Server nicht gelöscht.
django
file
storage
django-models
imagefield
narkeeso
quelle
quelle
Antworten:
Sie können das Signal
pre_delete
oderpost_delete
empfangen (siehe den Kommentar von @ toto_tico unten) und die Methode delete () für das FileField-Objekt aufrufen, also (in models.py):quelle
instance.file
Feld nicht leer ist, oder es kann (zumindest versuchen), das gesamte MEDIA_ROOT-Verzeichnis zu löschen. Dies gilt auch fürImageField(null=False)
Felder.post_delete
Signal zu verwenden, da es sicherer ist, wenn das Löschen aus irgendeinem Grund fehlschlägt. Dann würden weder das Modell noch die Datei gelöscht, um die Daten konsistent zu halten. Bitte korrigieren Sie mich, wenn mein Verständnispost_delete
und meinepre_delete
Signale falsch sind.Versuchen Sie es mit Django-Aufräumarbeiten
settings.py
quelle
Django 1.5-Lösung: Ich verwende post_delete aus verschiedenen Gründen, die für meine App intern sind.
Ich habe dies am Ende der Datei models.py festgehalten.
Das
original_image
Feld ist dasImageField
in meinemPhoto
Modell.quelle
NotImplementedError: This backend doesn't support absolute paths.
Sie können dies leicht beheben, indem Sie den Namenstorage.delete()
des Dateifelds anstelle des Pfads des Dateifelds an übergeben. Ersetzen Sie beispielsweise die letzten beiden Zeilen dieser Antwort durchstorage, name = photo.original_image.storage, photo.original_image.name
dannstorage.delete(name)
.mymodel.myimagefield.delete(save=False)
stattdessen verwenden. docs.djangoproject.com/de/dev/ref/files/file/…mymodel.myimagefield.delete(save=False)
auf verwendenpost_delete
? Mit anderen Worten, ich kann sehen, dass ich die Datei löschen kann. Können Sie die Datei jedoch löschen, wenn ein Modell mit dem Bildfeld gelöscht wird?post_delete
Sie tuninstance.myimagefield.delete(save=False)
, beachten Sie die Verwendung voninstance
.Dieser Code läuft auf Django 1.4 auch mit dem Admin-Panel gut.
Es ist wichtig, den Speicher und den Pfad abzurufen, bevor das Modell gelöscht wird. Andernfalls bleibt das Modell auch dann ungültig, wenn es gelöscht wird.
quelle
delete
Wird nicht immer aufgerufen, wenn eine Zeile gelöscht wird, müssen Sie Signale verwenden.Sie müssen die eigentliche Datei auf beiden
delete
und entfernenupdate
.quelle
Sie können ein Pre_delete- oder Post_delete-Signal verwenden:
https://docs.djangoproject.com/de/dev/topics/signals/
Die gleichen Gründe, aus denen das automatische Löschen von FileField entfernt wurde, gelten natürlich auch hier. Wenn Sie eine Datei löschen, auf die an einer anderen Stelle verwiesen wird, treten Probleme auf.
In meinem Fall schien dies angemessen zu sein, da ich ein dediziertes Dateimodell hatte, um alle meine Dateien zu verwalten.
Hinweis: Aus irgendeinem Grund scheint post_delete nicht richtig zu funktionieren. Die Datei wurde gelöscht, aber der Datenbankdatensatz blieb erhalten, was auch unter Fehlerbedingungen das Gegenteil von dem ist, was ich erwarten würde. pre_delete funktioniert jedoch einwandfrei.
quelle
post_delete
funktioniert es nicht, da dasfile_field.delete()
Modell standardmäßig in derfile_field.delete(False)
Datenbank gespeichertVielleicht ist es etwas spät. Am einfachsten ist es für mich jedoch, ein post_save-Signal zu verwenden. Nur um sich daran zu erinnern, dass Signale auch während eines QuerySet-Löschvorgangs ausgeführt werden, die Methode [model] .delete () jedoch während des QuerySet-Löschvorgangs nicht ausgeführt wird. Daher ist es nicht die beste Option, sie zu überschreiben.
core / models.py:
Kern / Signale.py
quelle
Diese Funktionalität wird in Django 1.3 entfernt, sodass ich mich nicht darauf verlassen würde.
Sie können die
delete
Methode des betreffenden Modells überschreiben , um die Datei zu löschen, bevor Sie den Eintrag vollständig aus der Datenbank entfernen.Bearbeiten:
Hier ist ein kurzes Beispiel.
quelle
MyModel.objects.all()[0].delete()
wird die Datei gelöscht, während diesMyModel.objects.all().delete()
nicht der Fall ist. Verwenden Sie Signale.Die Verwendung von post_delete ist mit Sicherheit der richtige Weg. Manchmal kann es jedoch zu Fehlern kommen und Dateien werden nicht gelöscht. Es gibt natürlich den Fall, dass Sie eine Reihe alter Dateien haben, die nicht gelöscht wurden, bevor post_delete verwendet wurde. Ich habe eine Funktion erstellt, die Dateien für Objekte basierend darauf löscht, ob die Datei, auf die das Objekt verweist, nicht vorhanden ist, dann Objekt löschen, wenn die Datei kein Objekt hat, dann auch löschen, kann sie auch basierend auf einem "aktiven" Flag für ein löschen Objekt .. Etwas, das ich den meisten meiner Modelle hinzugefügt habe. Sie müssen ihm die Objekte übergeben, die Sie überprüfen möchten, den Pfad zu den Objektdateien, das Dateifeld und ein Flag, um inaktive Objekte zu löschen:
So können Sie Folgendes verwenden:
quelle
Stellen Sie sicher, dass Sie " self " vor der Datei schreiben . so sollte das obige Beispiel sein
Ich habe das "Selbst" vor meiner Datei vergessen und das hat nicht funktioniert, da es im globalen Namespace aussah.
quelle
Wenn Sie bereits eine Anzahl nicht verwendeter Dateien in Ihrem Projekt haben und diese löschen möchten, können Sie das Dienstprogramm django django-unused-media verwenden
quelle
Django 2.x Lösung:
Es müssen keine Pakete installiert werden! In Django 2 ist es sehr einfach zu handhaben . Ich habe versucht, die folgende Lösung mit Django 2 und SFTP-Speicher zu verwenden (ich denke jedoch, dass dies mit allen Speichern funktionieren würde).
Schreiben Sie zuerst einen benutzerdefinierten Manager . Wenn Sie also Dateien eines Modells mithilfe von
objects
Methoden löschen möchten , müssen Sie einen [benutzerdefinierten Manager] [3] schreiben und verwenden (zum Überschreiben derdelete()
Methode vonobjects
):Jetzt müssen Sie löschen,
image
bevor Sie das Modell selbst löschen. Um das Modell dem Modell zuzuweisenCustomManager
, müssen Sie esobjects
in Ihrem Modell initialisieren:quelle
Ich habe möglicherweise einen Sonderfall, da ich die Option upload_to in meinem Dateifeld mit dynamischen Verzeichnisnamen verwende, aber die Lösung, die ich gefunden habe, war die Verwendung von os.rmdir.
In Modellen:
...
quelle