FYI, on_delete
พารามิเตอร์ในแบบจำลองจะย้อนกลับจากที่ฟังดูเหมือน คุณใส่on_delete
Foreign Key (FK) ในแบบจำลองเพื่อบอก django ว่าต้องทำอย่างไรถ้ารายการ FK ที่คุณชี้ไปยังบันทึกของคุณถูกลบ ตัวเลือกที่ร้านค้าของเรามีการใช้มากที่สุดคือPROTECT
, และCASCADE
SET_NULL
นี่คือกฎพื้นฐานที่ฉันคิดได้:
- ใช้
PROTECT
เมื่อ FK ของคุณชี้ไปที่ตารางค้นหาที่ไม่ควรเปลี่ยนจริง ๆ และแน่นอนไม่ควรทำให้ตารางของคุณเปลี่ยน หากใครพยายามลบรายการในตารางการค้นหานั้นPROTECT
ป้องกันไม่ให้ลบออกหากเชื่อมโยงกับบันทึกใด ๆ นอกจากนี้ยังป้องกันไม่ให้ django ลบบันทึกของคุณเพียงเพราะมันลบรายการในตารางการค้นหา ส่วนสุดท้ายนี้มีความสำคัญ หากใครบางคนจะลบเพศ "หญิง" จากตารางเพศของฉันฉันแน่นอนไม่ต้องการที่จะลบทันทีและทุกคนที่ฉันมีในตารางบุคคลของฉันที่มีเพศนั้น
- ใช้
CASCADE
เมื่อ FK ของคุณชี้ไปที่ระเบียน "หลัก" ดังนั้นหากบุคคลสามารถมีหลายรายการ PersonEthnicity (เขา / เธอสามารถเป็นชาวอเมริกันอินเดียน, สีดำและสีขาว) และบุคคลนั้นจะถูกลบฉันอยากจะลบรายการ PersonEthnicity "เด็ก" ใด ๆ พวกเขาไม่เกี่ยวข้องโดยไม่มีบุคคล
- ใช้
SET_NULL
เมื่อคุณไม่ต้องการคนที่จะได้รับอนุญาตให้ลบรายการบนโต๊ะมองขึ้น แต่คุณยังคงต้องการที่จะเก็บรักษาบันทึกของคุณ ตัวอย่างเช่นถ้าเป็นคนที่สามารถมีมัธยมศึกษา on_delete=SET_NULL
แต่มันไม่ได้เรื่องจริงๆกับผมว่าที่โรงเรียนมัธยมออกไปบนโต๊ะมองขึ้นของฉันฉันจะบอกว่า นี่จะทำให้คนของฉันบันทึกที่นั่น มันแค่ตั้งค่า FK ของโรงเรียนมัธยมให้กับบุคคลของฉันเป็นโมฆะ เห็นได้ชัดว่าคุณจะต้องให้null=True
FK นั้น
นี่คือตัวอย่างของโมเดลที่ทำทั้งสามอย่าง:
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'
ในฐานะที่เป็นชิ้นอาหารอันโอชะครั้งสุดท้ายคุณรู้หรือไม่ว่าหากคุณไม่ระบุon_delete
(หรือไม่ได้ระบุ) พฤติกรรมเริ่มต้นคือCASCADE
อะไร ซึ่งหมายความว่าหากมีคนลบรายการเพศในตารางเพศของคุณบันทึกบุคคลใด ๆ ที่มีเพศนั้นก็จะถูกลบด้วย!
ฉันจะพูดว่า "ถ้าตั้งข้อสงสัยไว้on_delete=models.PROTECT
" จากนั้นไปทดสอบใบสมัครของคุณ คุณจะทราบได้อย่างรวดเร็วว่า FK ใดควรติดป้ายกำกับค่าอื่นโดยไม่ทำอันตรายต่อข้อมูลใด ๆ ของคุณ
นอกจากนี้ยังเป็นที่น่าสังเกตว่าon_delete=CASCADE
จริงๆแล้วจะไม่ถูกเพิ่มลงในการย้ายข้อมูลใด ๆ ของคุณหากนั่นเป็นพฤติกรรมที่คุณเลือก ฉันเดาว่านี่เป็นเพราะมันเป็นค่าเริ่มต้นดังนั้นการวางon_delete=CASCADE
จึงเหมือนกับการไม่ใส่อะไรเลย