FYI, on_delete
modellerde parametre nasıl göründüğünden geriye doğru. on_delete
Django'ya kaydınızda işaret ettiğiniz FK girişi silinirse ne yapacağını söylemek için bir modele Yabancı Anahtar (FK) koydunuz . Seçenekler bizim dükkan çoğu kullanmış PROTECT
, CASCADE
ve SET_NULL
. İşte anladığım temel kurallar:
PROTECT
FK'niz gerçekten değişmemesi gereken ve tablonuzun değişmesine kesinlikle neden olmaması gereken bir arama tablosuna işaret ederken kullanın . Herhangi biri bu arama tablosundaki bir girişi silmeye çalışırsa PROTECT
, herhangi bir kayda bağlıysa silmelerini engeller. Ayrıca önler silmesini django senin bir görünüm tablo üzerinde bir girdi silindi sırf rekor. Bu son bölüm kritik. Birisi Cinsiyet tablomdaki "Kadın" cinsiyetini silecek olsaydı, CERTAINLY, bu benim cinsiyetim olan Kişi masamda bulunan tüm kişileri anında silmek istemezdim.
CASCADE
FK'niz bir "ebeveyn" kaydını işaret ettiğinde kullanın . Bir Kişi birçok PersonEthnicity girişleri olabilir Yani, eğer (o / o Amerikan Hint, Siyah ve Beyaz olabilir) ve Kişi yani edilir silinmiş, gerçekten ederim herhangi bir "çocuk" PersonEthnicity girişleri silinecek istiyorum. Kişi olmadan ilgisizdirler.
- Kullan
SET_NULL
ne zaman do insanlar görünüm tablo üzerinde bir girişi silmek için izin istiyor, ancak yine de kaydını bulundurmak istiyoruz. Örneğin, eğer bir kişi bir liseye sahip olabilirse, ancak o lisenin arama masama gidip gitmemesi benim için hiç önemli değil on_delete=SET_NULL
. Bu, Kişi kaydımı orada bırakacaktır; sadece Kişimdeki lise FK'sini boş olarak ayarlayacaktı. Açıkçası, null=True
bu FK'ye izin vermeniz gerekecek .
İşte her üç şeyi de yapan bir model örneği:
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'
Son bir nefis lokma olarak, eğer biliyor muydunuz yok belirtmek on_delete
(veya hiç), varsayılan davranıştır CASCADE
? Bu, birisi Cinsiyet tablonuzdaki bir cinsiyet girişini sildiyse, bu cinsiyete sahip Kişi kayıtlarının da silindiği anlamına gelir!
"Şüphe duyarsanız, hazırlayın" derdim on_delete=models.PROTECT
. Ardından uygulamanızı test edin. Verilerinizi tehlikeye atmadan hangi FK'lerin diğer değerleri etiketlemesi gerektiğini hızlı bir şekilde anlayacaksınız.
Ayrıca, on_delete=CASCADE
seçtiğiniz davranış buysa, taşıma işlemlerinizin hiçbirine gerçekten eklenmediğini belirtmek gerekir. Sanırım bu varsayılan on_delete=CASCADE
olduğu için koymak hiçbir şey koymakla aynı şeydir.