Ich habe ein Problem, weil ich ein Widget mit some_widget_instance.delete () lösche. Ich habe auch ein Modell namens WidgetFile mit einer override delete () -Methode, damit ich Dateien von meiner Festplatte löschen kann, wenn eine WidgetFile gelöscht wird. Das Problem, das ich habe, ist, dass wenn ich ein Widget lösche und WidgetFiles wie folgt damit verknüpft sind:
class WidgetFile(models.Model):
widget = models.ForeignKey(Widget)
Nun, wenn ich dieses Widget lösche, werden die Widget-Dateien gelöscht, aber die delete () -Methode wird nicht ausgelöst und erledigt meine zusätzlichen Festplatten-Aufgaben nicht. Jede Hilfe wird sehr geschätzt.
Ich habe es herausgefunden. Ich habe dies gerade auf das Widget-Modell gesetzt:
def delete(self):
files = WidgetFile.objects.filter(widget=self)
if files:
for file in files:
file.delete()
super(Widget, self).delete()
Dies löste die erforderliche delete () -Methode für jedes der verwandten Objekte aus, wodurch der Löschcode für meine benutzerdefinierte Datei ausgelöst wurde. Ja, es ist datenbankintensiver, aber wenn Sie versuchen, Dateien auf einer Festplatte zu löschen, ist es nicht so teuer, die Datenbank ein paar zusätzliche Male aufzusuchen.
Ich mache dasselbe und habe ein Nugget in den Django-Dokumenten entdeckt, über das Sie nachdenken sollten.
Überschreiben vordefinierter Modellmethoden
Überschreiben von Delete Beachten Sie, dass die delete () -Methode für ein Objekt nicht unbedingt aufgerufen wird, wenn Objekte mithilfe eines QuerySet-Objekts in großen Mengen gelöscht werden. Um sicherzustellen, dass die angepasste Löschlogik ausgeführt wird, können Sie Pre_Delete- und/oder Post_Delete-Signale verwenden.
Dies bedeutet, dass Ihr Snippet nicht immer das tut, was Sie wollen. Die Verwendung von Signalen ist eine bessere Option für den Umgang mit Löschungen.
Ich ging mit folgenden:
import shutil
from Django.db.models.signals import pre_delete
from Django.dispatch import receiver
@receiver(pre_delete)
def delete_repo(sender, instance, **kwargs):
if sender == Set:
shutil.rmtree(instance.repo)
Wenn Sie clear()
vor dem Löschen verwenden, werden alle Objekte aus dem zugehörigen Objektsatz entfernt.
siehe Django-folgenden-Beziehungen-rückwärts
beispiel:
group.link_set.clear()
group.delete()
Dies scheint nur sinnvoll zu sein, wenn genau ein Widget mit einem WidgetFile verbunden ist. In diesem Fall sollten Sie ein OneToOneField verwenden.
von Einzelbeispiele:
# Delete the restaurant; the waiter should also be removed
>>> r = Restaurant.objects.get(pk=1)
>>> r.delete()
Um dieses Problem auf eine mögliche Weise zu umgehen: VorlöschenSignal . (Das bedeutet keineswegs, dass es keine tatsächliche Lösung gibt.)
Es sollte so aussehen, wie auf der Django Seite beschrieben:
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def save(self, *args, **kwargs):
do_something()
super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.
do_something_else()
http://docs.djangoproject.com/de/dev/topics/db/models/#overriding-predefined-model-methods
sie haben vergessen, einige Argumente zu übergeben
Ist some_widget_instance
und Instanz von Widget
oder von WidgetFile
? Wenn es sich um eine Instanz von Widget
handelt, wird die benutzerdefinierte Funktion delete()
in der Klasse WidgetFile
nicht abgerufen.
Wenn Sie in Django 1.9 nur on_delete=models.CASCADE
für Feld definieren, werden alle verwandten Objekte beim Löschen entfernt.