Verhindern, löschen Sie in der Django-Modell
Habe ich ein setup wie diesem (vereinfacht für diese Frage):
class Employee(models.Model):
name = models.CharField(name, unique=True)
class Project(models.Model):
name = models.CharField(name, unique=True)
employees = models.ManyToManyField(Employee)
Wenn ein Mitarbeiter zu erreichen ist gelöscht, ich wollen, um zu überprüfen, ob er angeschlossen ist, um irgendwelche Projekte. Wenn ja, löschen sollte unmöglich sein.
Weiß ich über Signale und wie Sie arbeiten. Ich kann eine Verbindung zu den pre_delete
signal, und machen es eine exception werfen, wie ValidationError
. Dies verhindert löschen, aber es wird nicht ordnungsgemäß verarbeitet, die von Formularen und so.
Scheint dies eine situation, die anderen müssen laufen. Ich bin der Hoffnung, jemand kann eine elegante Lösung.
Dies ist nicht machbar, nur mit Python-code; die Datenbank selbst müssen modifiziert werden, wie gut.
Vielen Dank für Ihren Kommentar. Ich bin auf der Suche nach der Python - /Django-Teil zuerst und sehen, wie weit das bekommt mir in meinem app.
Vielen Dank für Ihren Kommentar. Ich bin auf der Suche nach der Python - /Django-Teil zuerst und sehen, wie weit das bekommt mir in meinem app.
InformationsquelleAutor dyve | 2011-01-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
War ich auf der Suche nach einer Antwort auf dieses problem, war nicht in der Lage, einen guten finden, das funktioniert für beide Modelle.Modell.delete() und QuerySet.löschen(). Ich ging zusammen und, irgendwie, Durchführung Steve K die Lösung. Ich habe diese Lösung, um sicherzustellen, dass ein Objekt (Mitarbeiter in diesem Beispiel), können nicht aus der Datenbank gelöscht werden, so oder so, aber auf inaktiv gesetzt.
Es ist eine späte Antwort.. nur zum Wohle der anderen Menschen auf der Suche, ich Stelle meine Lösung hier.
Hier ist der code:
Verwendung:
oder in den admin:
Diese Lösung ist etwa das grundlegende Prinzip (und elegant) verhindern, dass ein löschen in Django. Überschreiben der delete-Methode macht es einfach, passend für die Fragesteller ist Anwendungsfall.
Vielen Dank für Ihre Antwort auch sein mag, es ist ein Ausgangspunkt, aber ich Tat dies in einer anderen Art und Weise und haben einige Fragen über, die. Ich würde schätzen, wenn Sie überprüfen könnten, meine question und Hole mir ein feedback.
Ihre Methode, die Sie vorgeschlagen, ist nicht geeignet für die Löschung, weil Sie haben zu prüfen, die
project
Feld innerhalb der Abfrage löschen oder Sie rufendelete
Methode in queryset löschen-Funktion für jedes Objekt in der Abfrage, die weder von Ihnen eine praktikable und effiziente Möglichkeit, im großen Maßstab Daten-Modelle(Zum Beispiel, wenn Sie überprüfen müssen, vieleManyToMany
Felder)Diese Methode ist natürlich nicht geeignet für große Datenmengen bei der Verwendung von zusätzlichen Abfragen zu check-Einschränkungen. Die Optimierung für solche Szenarien sollten vorsichtig sein, wenn sich je nach Szenario. In Django am häufigsten Lösungen wie task-server-oder raw-Abfragen angewendet werden, in einem solchen Fall.
InformationsquelleAutor Elwin
Wenn Sie wissen, dass es nie mehr eine Masse Mitarbeiters zu löschen versucht, kann man einfach überschreiben
delete
auf Ihr Modell und nur callsuper
wenn es eine Legale Betrieb.Leider nichts, das nennen könnte
queryset.delete()
gehen direkt zu SQL:http://docs.djangoproject.com/en/dev/topics/db/queries/#deleting-objects
Aber ich sehe nicht, dass viel von einem problem, weil Sie-die einen schreiben den code und kann sicher es gibt nie eine
queryset.delete()
auf die Mitarbeiter. Rufen Siedelete()
manuell.Ich hoffe das löschen von Mitarbeitern ist relativ selten.
Können Sie kümmern sich um Masse löscht durch schreiben 2 Klassen : eine, die erbt Modelle.Manager und andere Erben-Modelle.Abfrage.QuerySet Die erste überschreiben get_query_set, die eine Instanz der zweiten Klasse. Das QuerySet abgeleiteten Klasse überschreiben der delete () - Methode. Diese delete-Methode wird Durchlaufen der Instanz der Klasse und Aufruf von delete() auf jedes Element. Hoffe, das ist klar.
InformationsquelleAutor Yuji 'Tomita' Tomita
Diese würden wrap-up-Lösung aus der Umsetzung meiner app. Einige code-form LWN Antwort.
Gibt es 4 Situationen, dass Ihre Daten gelöscht:
delete()
auf Model-Instanz:project.delete()
delete()
auf QuerySet innstance:Project.objects.all().delete()
Zwar gibt es nichts viel Sie tun können, mit dem ersten Fall, die anderen drei können feinkörnige gesteuert.
Eine Beratung ist, dass in den meisten Fällen, sollten Sie nie löschen Sie die Daten selbst, da diese Daten spiegeln die Geschichte und die Nutzung unserer Anwendung. Einstellung auf
active
Boolean-Feld ist bevorzugt, statt.Um zu verhindern, dass
delete()
auf Model-Instanz, Unterklassedelete()
im Modell-Erklärung:Während
delete()
auf QuerySet-Instanz muss ein kleines setup mit einem benutzerdefinierten Objekt-manager wie in LWN Antwort.Wickeln diese bis zu einer wiederverwendbaren Implementierung:
Nutzung, nur Unterklasse
ActiveModel
Klasse:Immer noch unser Objekt können noch gelöscht werden, wenn irgendeiner Ihrer ForeignKey Felder gelöscht:
Dies kann verhindert werden durch Zugabe von on_delete argument von Modell field:
Standardwert
on_delete
istCASCADE
wodurch wird die Instanz gelöscht, indemPROTECT
statt, die heben einenProtectedError
(eine Unterklasse vonIntegrityError
). Ein weiterer Zweck ist, dass der ForeignKey-Daten gehalten werden sollten als Referenz.InformationsquelleAutor anhdat
Ich habe einen Vorschlag, aber ich bin nicht sicher, es ist besser als Ihre derzeitige Idee. Ein Blick auf die Antwort hier für einen weit entfernten, aber nicht losgelöst problem, können Sie überschreiben, in der django-admin-verschiedene Aktionen, die durch im wesentlichen löschen Sie diese und verwenden Sie Ihre eigenen. So, zum Beispiel, wenn Sie haben:
Wenn Sie nicht mit dem django-admin wie mich, dann erstellen Sie einfach, dass der check-in Ihren UI-Logik, bevor Sie dem Benutzer erlauben, um das Objekt zu löschen.
InformationsquelleAutor
Ich würde gerne vorschlagen, eine weitere variation auf LWN und anhdat ist Antworten, worin wir verwenden eine
deleted
- Feld statt einactive
Feld und wir schließen die "gelöschten" Objekte aus der Standard-queryset, so behandeln Sie diese Objekte als nicht mehr vorhanden, es sei denn, wir spezifisch sind.Verwendung:
Wie gesagt in anhdat Antwort, stellen Sie sicher, dass die
on_delete
Eigenschaft auf ForeignKeys auf Ihrem Modell zu vermeiden, cascade-Verhalten, z.B.Hinweis:
Ähnlicher Funktionalität ist enthalten in
django-Modell-utils
'sSoftDeletableModel
wie ich gerade entdeckt. Wert heraus überprüfen. Kommt mit einigen anderen praktischen Dinge.InformationsquelleAutor Felix Böhme
Für diejenigen, die verweisen auf diese Fragen mit dem gleichen Problem mit einem
ForeignKey
Beziehung die richtige Antwort wäre die Verwendung von Djago ' son_delete=models.PROTECT
Feld auf derForeignKey
Beziehung. Dies wird verhindern, dass löschen von Objekt -, foreign key-Verknüpfungen zu. Dies funktioniert NICHT für fürManyToManyField
Beziehungen (wie besprochen, in diese Frage), aber funktioniert großartig fürForeignKey
Felder.So, wenn die Modelle waren wie das, das funktionieren würde, um zu verhindern, dass die Löschung von
alle
Employee
Objekt, das einen oder mehrProject
Objekt(en) zugeordnet:Dokumentation finden Sie HIER.
InformationsquelleAutor Colton Hicks