2009-10-28 12 views
10

मैं इसे सहेजने के बाद रिकॉर्ड को तुरंत अपडेट करने का प्रयास कर रहा हूं। इस उदाहरण व्यर्थ प्रतीत लेकिन कल्पना के बाद डेटा के लिए कुछ अतिरिक्त जानकारी प्राप्त करने और रिकॉर्ड को अपडेट करने सहेजा जाता है हम एक एपीआई का उपयोग करने की आवश्यकता हो सकती:django में post_save तुरंत उदाहरण अपडेट करने के लिए

def my_handler(sender, instance=False, **kwargs): 
    t = Test.objects.filter(id=instance.id) 
    t.blah = 'hello' 
    t.save() 

class Test(models.Model): 
    title = models.CharField('title', max_length=200) 
    blah = models.CharField('blah', max_length=200) 

post_save.connect(my_handler, sender=Test) 

तो 'अतिरिक्त' क्षेत्र 'हैलो' के लिए सेट किया जाता है प्रत्येक बचाओ के बाद। सही बात? लेकिन यह काम नहीं कर रहा है।

कोई विचार?

+0

शायद आप वर्णन कर सकते हैं कि यह कैसे काम नहीं कर रहा है? पहले ब्लश पर, ऐसा लगता है कि यह एक अनंत लूप बना देगा, क्योंकि post_save कॉल सेव करता है, जिसे post_save, आदि का आह्वान करना चाहिए। शायद Django रिकर्सन को रोक रहा है? –

+0

मुझे वहां एक अनंत लूप दिखाई देता है। T.save() के बाद एक post_save सिग्नल भेजा जाता है, अनुमान लगाएं कि कौन सा फ़ंक्शन कॉल किया जाता है ... – stefanw

+0

ओह, मैं इंप्रेशन के तहत था कि Django दूसरी सहेजने को फिर से सहेजने नहीं देगा? मुझे नहीं लगता। इस मामले में, आप सही हैं। यह एक अनंत लूप होगा। लेकिन मैं लूप या कुछ नहीं देख रहा हूँ। – givp

उत्तर

18

जब आप प्रेषक वर्ग की किसी ऑब्जेक्ट को अपडेट करने के लिए पोस्ट_सेव सिग्नल का उपयोग करके स्वयं को पाते हैं, तो संभावना है कि आपको इसके बजाय सेव विधि को ओवरराइड करना चाहिए। आपके मामले में, मॉडल परिभाषा इस तरह दिखेगी:

class Test(models.Model): 
    title = models.CharField('title', max_length=200) 
    blah = models.CharField('blah', max_length=200) 

    def save(self, force_insert=False, force_update=False): 
     if not self.blah: 
      self.blah = 'hello' 
     super(Test, self).save(force_insert, force_update) 
+1

यदि वह व्यवस्थापक मॉडल में ऐसा कर रहा है, तो post_save मौजूदा व्यवस्थापक मॉडल को उप-वर्गीकरण और सहेजने से ओवरराइड करने से बेहतर समाधान है। –

+0

@ पॉल मैकमिलन क्यों? –

+0

'का उपयोग करके = गलत' की आवश्यकता है 'सेव' विधि तर्क तर्क सूची में Django 1.3 और उच्च – eviltnan

6

क्या पोस्ट_सेव हैंडलर उदाहरण नहीं लेता है? आप इसका उपयोग क्यों फ़िल्टर कर रहे हैं? क्यों नहीं बस करो: क्योंकि यह लूप

def my_handler(sender, instance=False, created, **kwargs): 
    if created: 
    instance.blah = 'hello' 
    instance.save() 

आपका मौजूदा कोड काम नहीं करता है, और Test.objects.filter(id=instance.id) एक प्रश्न सेट, नहीं एक वस्तु देता है। एक ऑब्जेक्ट सीधे प्राप्त करने के लिए, Queryset.get() का उपयोग करें। लेकिन आपको इसे करने की ज़रूरत नहीं है। बनाया गया तर्क इसे लूपिंग से रोकता है, क्योंकि यह केवल पहली बार सेट करता है।

सामान्य रूप से, जब तक आपको पोस्ट_सेव सिग्नल का उपयोग करने की आवश्यकता नहीं होती है, तो आपको अपनी ऑब्जेक्ट की सेव() विधि को ओवरराइड करना चाहिए।

+0

मैंने वास्तव में कोशिश की कि इसका कोई फायदा न हो। लेकिन अगर उपरोक्त लोग सही हैं, तो मैं इसे वैसे भी नहीं कर सकता क्योंकि यह सिर्फ post_save लूप में फंस जाएगा। – givp

+0

बनाए गए ध्वज का उपयोग करके इसे आज़माएं। मुझे लगता है कि आपकी समस्या को ठीक करना चाहिए, क्योंकि निर्मित लूप के माध्यम से बनाया गया है। –

+1

सिग्नल का उपयोग कब करें और सहेजने के लिए ओवरराइड करने के बारे में अधिक जानकारी के लिए आप इस प्रश्न को देखना चाहेंगे: http://stackoverflow.com/questions/170337/django-signals-vs-overriding-save-method –

संबंधित मुद्दे