Zu Ihrer Information, der on_delete
Parameter in Modellen ist rückwärts von dem, wie es sich anhört. Sie setzen on_delete
einen Fremdschlüssel (FK) für ein Modell ein, um Django mitzuteilen, was zu tun ist, wenn der FK-Eintrag, auf den Sie in Ihrem Datensatz zeigen, gelöscht wird. Die Optionen unserem Shop verwendet haben , die meisten sind PROTECT
, CASCADE
und SET_NULL
. Hier sind die Grundregeln, die ich herausgefunden habe:
- Verwenden
PROTECT
Sie diese Option, wenn Ihr FK auf eine Nachschlagetabelle zeigt, die sich wirklich nicht ändern sollte und die sicherlich nicht dazu führen sollte, dass sich Ihre Tabelle ändert. Wenn jemand versucht, einen Eintrag in dieser Nachschlagetabelle zu löschen, wird PROTECT
verhindert , dass er ihn löscht, wenn er an einen Datensatz gebunden ist. Es verhindert auch, dass Django Ihren Datensatz löscht , nur weil ein Eintrag in einer Nachschlagetabelle gelöscht wurde. Dieser letzte Teil ist kritisch. Wenn jemand das Geschlecht "weiblich" aus meiner Geschlechtstabelle löschen würde, würde ich BESTIMMT NICHT wollen, dass dadurch sofort alle Personen gelöscht werden, die ich in meiner Personentabelle hatte und die dieses Geschlecht hatten.
- Verwenden
CASCADE
Sie diese Option, wenn Ihre FK auf einen "übergeordneten" Datensatz zeigt. Also, wenn eine Person viele PersonEthnicity Einträge haben kann (kann er / sie indianischer, Schwarz und Weiß sein), und diese Person wird gelöscht, ich wirklich würde wollen alle „Kind“ PersonEthnicity Einträge gelöscht werden. Sie sind ohne die Person irrelevant.
- Verwenden
SET_NULL
Sie diese Option, wenn Sie möchten, dass Personen einen Eintrag in einer Nachschlagetabelle löschen dürfen, Ihre Aufzeichnung jedoch beibehalten werden soll. Wenn zum Beispiel eine Person eine HighSchool haben kann, es mir aber nicht wirklich wichtig ist, ob diese High School auf meinem Nachschlagetisch verschwindet, würde ich sagen on_delete=SET_NULL
. Dies würde meine Person Aufzeichnung dort draußen lassen; es würde nur die High-School-FK auf meiner Person auf null setzen. Natürlich müssen Sie null=True
diese FK zulassen .
Hier ist ein Beispiel eines Modells, das alle drei Dinge tut:
class PurchPurchaseAccount(models.Model):
id = models.AutoField(primary_key=True)
purchase = models.ForeignKey(PurchPurchase, null=True, db_column='purchase', blank=True, on_delete=models.CASCADE) # If "parent" rec gone, delete "child" rec!!!
paid_from_acct = models.ForeignKey(PurchPaidFromAcct, null=True, db_column='paid_from_acct', blank=True, on_delete=models.PROTECT) # Disallow lookup deletion & do not delete this rec.
_updated = models.DateTimeField()
_updatedby = models.ForeignKey(Person, null=True, db_column='_updatedby', blank=True, related_name='acctupdated_by', on_delete=models.SET_NULL) # Person records shouldn't be deleted, but if they are, preserve this PurchPurchaseAccount entry, and just set this person to null.
def __unicode__(self):
return str(self.paid_from_acct.display)
class Meta:
db_table = u'purch_purchase_account'
Wussten Sie als letzten Leckerbissen, dass das Standardverhalten lautet , wenn Sie nichts angeben on_delete
(oder nicht angeben ) CASCADE
? Dies bedeutet, dass, wenn jemand einen Geschlechtseintrag in Ihrer Gender-Tabelle gelöscht hat, auch alle Personendatensätze mit diesem Geschlecht gelöscht wurden!
Ich würde sagen: "Wenn Sie Zweifel haben, setzen Sie on_delete=models.PROTECT
." Dann testen Sie Ihre Anwendung. Sie werden schnell herausfinden, welche FKs mit den anderen Werten gekennzeichnet werden sollten, ohne Ihre Daten zu gefährden.
Es ist auch erwähnenswert, dass on_delete=CASCADE
keine Ihrer Migrationen tatsächlich hinzugefügt wird, wenn dies das von Ihnen ausgewählte Verhalten ist. Ich denke, das liegt daran, dass es die Standardeinstellung ist. Putten on_delete=CASCADE
ist also dasselbe wie Putten nichts.