Django सिग्नल बनाम सेविंग मेथड


89

मुझे इसके चारों ओर अपना सिर लपेटने में परेशानी हो रही है। अभी मेरे पास कुछ मॉडल हैं जो इस तरह के दिखते हैं:

 def Review(models.Model)
    ...fields...
    overall_score = models.FloatField(blank=True)

def Score(models.Model)
    review = models.ForeignKey(Review)
    question = models.TextField()
    grade = models.IntegerField()

एक समीक्षा में कई "स्कोर" होते हैं, समग्र_ स्कोर स्कोर का औसत होता है। जब कोई समीक्षा या स्कोर सहेजा जाता है, तो मुझे समग्र_स्कोर औसत को पुनर्गणना करने की आवश्यकता है। अभी मैं एक ओवरराइड सेव विधि का उपयोग कर रहा हूं। क्या Django के सिग्नल डिस्पैचर के उपयोग से कोई लाभ होगा?

जवाबों:


84

सेव / डिलीट सिग्नल आमतौर पर उन परिस्थितियों में अनुकूल होते हैं, जहाँ आपको बदलाव करने की ज़रूरत होती है, जो सवाल में मॉडल के लिए पूरी तरह से विशिष्ट नहीं हैं, या उन मॉडलों पर लागू किया जा सकता है जिनमें कुछ सामान्य है, या मॉडल भर में उपयोग के लिए कॉन्फ़िगर किया जा सकता है।

ओवरराइड saveविधियों में एक सामान्य कार्य एक मॉडल में कुछ पाठ क्षेत्र से स्लग की स्वचालित पीढ़ी है। यह कुछ का एक उदाहरण है, यदि आपको कई मॉडलों के लिए इसे लागू करने की आवश्यकता है, तो एक pre_saveसिग्नल का उपयोग करने से लाभ होगा , जहां सिग्नल हैंडलर स्लग फ़ील्ड का नाम और फ़ील्ड का नाम स्लग से उत्पन्न कर सकता है। एक बार जब आपके पास ऐसा कुछ हो जाता है, तो आपके द्वारा लगाई गई कोई भी बढ़ी हुई कार्यक्षमता सभी मॉडलों पर भी लागू होगी - जैसे कि जिस स्लग को आप मॉडल के प्रकार के लिए जोड़ने जा रहे हैं, उसे देखने के लिए, विशिष्टता सुनिश्चित करने के लिए।

पुन: प्रयोज्य अनुप्रयोगों को अक्सर संकेतों के उपयोग से लाभ होता है - यदि वे जो कार्यक्षमता प्रदान करते हैं, उन्हें किसी भी मॉडल पर लागू किया जा सकता है, वे आम तौर पर (जब तक कि यह अपरिहार्य नहीं है) उपयोगकर्ताओं को सीधे इसका लाभ उठाने के लिए अपने मॉडल को संशोधित करने की आवश्यकता नहीं होगी।

उदाहरण के लिए, django-mptt के साथ , मैंने pre_saveसंकेत का उपयोग खेतों के एक सेट को प्रबंधित करने के लिए किया, जो मॉडल के लिए एक पेड़ की संरचना का वर्णन करता है जो बनाने या अपडेट pre_deleteहोने वाली है और हटाए जा रहे ऑब्जेक्ट के लिए पेड़ की संरचना के विवरण को हटाने का संकेत और इसका पूरा इसके पहले वस्तुओं का उप-वृक्ष और वे हटा दिए जाते हैं। संकेतों के उपयोग के कारण, उपयोगकर्ताओं को उनके लिए इस प्रबंधन को करने के लिए अपने मॉडल में जोड़ने या संशोधित करने saveया deleteउन्हें करने की आवश्यकता नहीं है, उन्हें बस django-mptt को यह बताना होगा कि वे किन मॉडलों को प्रबंधित करना चाहते हैं।


क्या होगा यदि सिग्नल हैंडलर एक अपवाद को ट्रिगर करता है? मुझे लगता है कि उन्हें अपवादों को ट्रिगर नहीं करना चाहिए, अन्यथा वे एक अच्छे फिट नहीं हैं। क्या मै गलत हु?
एक्स-यूरी

20

तुम ने पूछा था:

क्या Django के सिग्नल डिस्पैचर के उपयोग से कोई लाभ होगा?

मुझे यह django डॉक्स में मिला:

ओवरराइड किए गए मॉडल तरीकों को थोक संचालन पर नहीं कहा जाता है

ध्यान दें कि किसी ऑब्जेक्ट के लिए डिलीट () विधि को आवश्यक रूप से तब नहीं बुलाया जाता है जब एक क्वेरी के उपयोग से थोक में वस्तुओं को हटा दिया जाता है या कैस्केडिंग हटाने के परिणामस्वरूप। यह सुनिश्चित करने के लिए कि कस्टमाइज्ड डिलीट लॉजिक निष्पादित हो जाए, आप pre_delete और / या post_delete सिग्नल का उपयोग कर सकते हैं।

दुर्भाग्यवश, बल्क में ऑब्जेक्ट्स बनाते या अपडेट करते समय कोई वर्कअराउंड नहीं होता है, क्योंकि सेव (), प्री_स्वे और पोस्ट_सेव में से किसी को भी नहीं बुलाया जाता है।

से: पूर्वनिर्धारित मॉडल विधियों को ओवरराइड करना


3
Django व्यवस्थापक सूची दृश्य बल्क डिलीट का उपयोग करता है ... इस tidbit में आने तक उलझन में था।
एन। बालारो

7
यह भी कहता है, "दुर्भाग्य से, बल्क में ऑब्जेक्ट्स बनाते या अपडेट करते समय वर्कअराउंड नहीं होता है, क्योंकि कोई भी सेव (), प्री_स्वे, और पोस्ट_सेव को नहीं कहा जाता है।" - तो मुझे नहीं लगता कि यह इन तरीकों के बीच एक व्यापार है।
कोरी

यह दोनों तरीकों पर लागू होता है, इसलिए इसका उत्तर है: "नहीं, saveविधि का पालन करने के विपरीत संकेतों का उपयोग करने का कोई लाभ नहीं है "?
फ़्लिक डेम

3

यदि आप उन संकेतों का उपयोग करेंगे जो आप समीक्षा स्कोर को अपडेट करने में सक्षम होंगे तो हर बार संबंधित स्कोर मॉडल सहेजा जाता है। लेकिन अगर मुझे इस तरह की कार्यक्षमता की आवश्यकता नहीं है, तो मुझे इसे सिग्नल में डालने का कोई कारण नहीं दिखता है, यह बहुत ही मॉडल से संबंधित सामान है।



1

बल्क डिलीट ( ऑब्जेक्ट्स .delete()पर विधि QuerySet) के बारे में Django डॉक्स से छोटा जोड़ :

ध्यान रखें कि यह, जब भी संभव हो, विशुद्ध रूप से SQL में निष्पादित किया जाना चाहिए, और इसलिए व्यक्तिगत ऑब्जेक्ट इंस्टेंसेस के डिलीट () तरीके जरूरी प्रक्रिया के दौरान नहीं बुलाए जाएंगे। यदि आपने एक मॉडल वर्ग पर एक कस्टम डिलीट () विधि प्रदान की है और यह सुनिश्चित करना चाहते हैं कि इसे कहा जाता है, तो आपको उस मॉडल के उदाहरणों को "मैन्युअल रूप से" डिलीट करने की आवश्यकता होगी (जैसे, एक क्वेरीसेट पर पुनरावृत्ति करके और डिलीट () को कॉल करके () प्रत्येक ऑब्जेक्ट व्यक्तिगत रूप से) एक क्वेरीस के बल्क डिलीट () पद्धति का उपयोग करने के बजाय।

https://docs.djangoproject.com/en/1.11/topics/db/queries/#deleting-objects

और बल्क अपडेट ( ऑब्जेक्ट .update()पर विधि QuerySet):

अंत में, एहसास होता है कि अपडेट () SQL स्तर पर एक अपडेट करता है और इस प्रकार, अपने मॉडल पर किसी भी सेव () तरीके को कॉल नहीं करता है, और न ही यह pre_save या post_save सिग्नल का उत्सर्जन करता है (जो कि मॉडल को सहेजने का परिणाम हैं।) ))। यदि आप किसी मॉडल को कस्टम सेव () विधि, उन पर लूप और कॉल सेव () के लिए रिकॉर्ड का एक गुच्छा अपडेट करना चाहते हैं

https://docs.djangoproject.com/en/2.1/ref/models/querysets/#update


क्या यह दोनों पर लागू नहीं होता है?
फ़्लिक डेम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.