2011-07-11 15 views
7

मेरे पास एक Django 1.3 ऐप है जिसके लिए मैं डीबी माइग्रेशन के लिए दक्षिण 0.7.3 का उपयोग कर रहा हूं। मुझे एक समस्या है जहां on_delete=models.SET_NULL नियम मूल रूप से हटाए जाने पर फ़ायरिंग प्रतीत नहीं होता है, इस प्रकार मुझे अंतर्निहित डीबी (जो पोस्टग्रेस 8.4 है) से बाधा उल्लंघन दे रहा है।क्या Django डीबी ऑन-डिलीट नियमों को लागू करना चाहता है?

इकाई defns के प्रासंगिक भागों हैं:

class AccessPeriod: 
    .... 

class Payment: 
    period = models.ForeignKey( 
     AccessPeriod, related_name = "payments", db_index = True, 
     null = True, on_delete = models.SET_NULL) 

कुछ खुदाई के बाद, मुझे पता चला कि दक्षिण वास्तव में एसक्यूएल यह माइग्रेशन के लिए उत्पन्न करता है में ON DELETE खंड सम्मिलित नहीं है, इसलिए डीबी निश्चित रूप से नहीं है

http://south.aeracode.org/ticket/763

तब मैं on_delete नियम है, जो राज्य (मेरे जोर) के लिए Django डॉक्स पढ़ें:: टूटे हुए रिश्तों पर ही समाप्त करते हुये क्या करने जा

जब एक वस्तु एक ForeignKey द्वारा संदर्भित हटा दी जाती है, जैंगो डिफ़ॉल्ट द्वारा emulates हटाना कैस्केड और भी पर एसक्यूएल बाधा के व्यवहार ForeignKey युक्त वस्तु हटा देता है। यह व्यवहार on_delete तर्क निर्दिष्ट करके ओवरराइड किया जा सकता है।

"emulates" भाग मेरे लिए सुझाव दिया है कि Django on_delete स्वयं के व्यवहार को लागू करने के लिए कोशिश करता है और अंतर्निहित डीबी पर निर्भर नहीं करता स्वचालित रूप से लेनदेन के भाग के रूप में इस पर अमल करने, इस प्रकार दक्षिण बग अप्रासंगिक बना रही है।

मैं Django स्रोत में db/models/deletion.py के माध्यम से एक प्रहार था और SET()/SET_NULL() और collect() यह निश्चित रूप से Django की तरह लगता है के कार्यान्वयन के आधार पर यह अपने आप करने के लिए माना जाता है, फिर भी, अगर मैं Django व्यवस्थापक से एक AccessPeriod को हटाने का प्रयास , मुझे आईडी के लिए भुगतान तालिका पर बाधा उल्लंघन मिलता है, जो अभी भी संदर्भित है, जिसे अब हटा दिया गया है, यानी ऐसा लगता है कि Payment.period पर रिलेशनशिप पर पर कॉलिंग पर कॉल के हिस्से के रूप में है।

क्या मैं यहां कुछ गलत कर रहा हूं, या गलत समझ रहा हूं कि Django क्या कर रहा है? बस डीईबीटीई नियम को स्वयं डालने के लिए डीबी को मैन्युअल रूप से हैक करने से बचने की कोशिश कर रहा है, जो बेहद भंगुर और भयानक लगता है।

+0

यदि पोस्टग्रेज़ विफल होने पर आपको स्टैक ट्रेस मिलता है, तो शायद यह कहां होगा कि यह गलत कहां जा रहा है। यह ऐसा कुछ हो सकता है जिसे आपने अनदेखा किया हो। – leech

उत्तर

4

मेरे विशिष्ट मामले में, मैंने अपने मॉडल.py कोड में मॉडलएडमिन इनलाइन की घोषणाओं के लिए इस बग का पता लगाया है, जिससे मेरे मॉडल वर्गों को गलत तरीके से तत्काल किया जा सकता है, on_delete व्यवहार का सबसे अधिक दुष्प्रभाव व्यवहार होता है। मेरे प्रतिबद्ध संदेश से:

डीजेगो डीबी में कैस्केडिंग डिलीट ठीक से नहीं किया जा रहा है।

बाहर कर देता है यह वास्तव में महत्वपूर्ण है models.py में वैश्विक क्षेत्र में अपने ModelAdmins की घोषणा नहीं करने के लिए, नहीं तो सभी रिश्तों विभिन्न मॉडलों के बीच गणना करने के पहले सभी मॉडलों भरी हुई हैं और उनमें से बहुत सारे बाहर छोड़ दिया जाए। वास्तव में Django दस्तावेज़ीकरण में इस बारे में भावनात्मक नहीं है।

तो अपने मूल (टूट) कोड में, मैं प्रत्येक मॉडल यह तुरंत बाद घोषणा की, एक ला के लिए ModelAdmin होगा:

class AccessPeriod(models.Model): 
    .... 

class AccessPeriodAdmin(models.ModelAdmin): 
    .... 

# This causes the metaclass setup for AccessPeriod to happen right now, 
# and since related models for AccessPeriod are not all declared yet, 
# relationship handling behaviour becomes broken for AccessPeriod 
admin.site.register(AccessPeriod, AccessPeriodAdmin) 

class Payment(models.Model): 
    .... 

class PaymentAdmin(models.ModelAdmin): 
    .... 

# Same effect on the Payment model here  
admin.site.register(Payment, PaymentAdmin) 

समाधान myapp/models.py से बाहर सभी ModelAdmin घोषणाओं स्थानांतरित करने के लिए था और myapp/admin.py में ताकि सभी वर्ग घोषणाओं के संचालन के बाद प्रत्येक वर्ग के लिए सभी मेटाक्लास सेटअप होता है, और फिर सभी रिश्ते फिर से ठीक से व्यवहार करना शुरू कर देते हैं।