FYI करें, on_delete
मॉडल में पैरामीटर जैसा दिखता है उससे पीछे की ओर है। आपने on_delete
django को यह बताने के लिए एक मॉडल पर एक विदेशी कुंजी (FK) डाल दी है कि यदि FK प्रविष्टि जिसे आप अपने रिकॉर्ड पर इंगित कर रहे हैं, हटा दी जाए तो क्या करें। विकल्प हमारी दुकान का इस्तेमाल किया है सबसे कर रहे हैं PROTECT
, CASCADE
और SET_NULL
। यहाँ बुनियादी नियम दिए गए हैं:
- का प्रयोग करें
PROTECT
जब आपके FK एक लुक-अप तालिका की ओर इशारा करते है कि वास्तव में नहीं बदल रहा है किया जाना चाहिए और कहा कि निश्चित रूप से परिवर्तन करने के लिए अपनी मेज का कारण नहीं होना चाहिए। यदि कोई भी उस लुक-अप टेबल पर एक प्रविष्टि को हटाने की कोशिश करता है, PROTECT
तो उसे किसी भी रिकॉर्ड से बंधे होने पर उसे हटाने से रोकता है। यह केवल आपके रिकॉर्ड को हटाने से django को रोकता है क्योंकि इसने लुक-अप टेबल पर एक प्रविष्टि हटा दी है। यह अंतिम भाग महत्वपूर्ण है। अगर कोई मेरी लिंग तालिका से "महिला" लिंग को हटाना चाहता था, तो मैं मुख्य रूप से नहीं चाहूंगा कि मेरे पर्सन टेबल में मौजूद किसी भी और सभी लोगों को तुरंत हटा दिया जाए।
CASCADE
जब आपका FK "पैरेंट" रिकॉर्ड की ओर इशारा कर रहा हो तब उपयोग करें । तो, एक व्यक्ति कई PersonEthnicity प्रविष्टियों हो सकता है अगर (वह / वह अमेरिकी भारतीय, काले और सफेद हो सकता है), और कहा कि व्यक्ति है नष्ट कर दिया, मैं वास्तव में चाहते हैं चाहते हैं किसी भी "बच्चा" PersonEthnicity प्रविष्टियों हटाए जाने के लिए। वे व्यक्ति के बिना अप्रासंगिक हैं।
- उपयोग करें
SET_NULL
जब आप चाहते हैं कि लोगों को एक लुक-अप टेबल पर एक प्रविष्टि को हटाने की अनुमति दी जाए, लेकिन आप अभी भी अपने रिकॉर्ड को संरक्षित करना चाहते हैं। उदाहरण के लिए, यदि एक व्यक्ति के पास हाईस्कूल हो सकता है, लेकिन यह वास्तव में मेरे लिए मायने नहीं रखता है अगर वह हाई-स्कूल मेरे लुक-अप टेबल पर चला जाता है, तो मैं कहूंगा on_delete=SET_NULL
। यह मेरा व्यक्ति रिकॉर्ड वहाँ छोड़ देगा; यह सिर्फ हाई-स्कूल एफके को मेरे व्यक्ति पर शून्य करने के लिए निर्धारित करेगा। जाहिर है, आपको null=True
उस एफके पर अनुमति देनी होगी ।
यहाँ एक मॉडल का उदाहरण दिया गया है जो तीनों चीजों को करता है:
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
कुछ भी नहीं डालने के रूप में एक ही बात है।