Django
सिग्नल
खोज…
पैरामीटर
कक्षा / विधि | क्यों |
---|---|
UserProfile () क्लास | UserProfile वर्ग Django डिफ़ॉल्ट उपयोगकर्ता मॉडल का विस्तार करता है। |
create_profile () विधि | जब भी कोई Django उपयोगकर्ता मॉडल post_save सिग्नल रिलीज़ होता है , तो create_profile () पद्धति निष्पादित होती है । |
टिप्पणियों
अब, विवरण।
जब यह होता है तो Django सिग्नल आपके कुछ कार्यों के ऐप को सूचित करने का एक तरीका है (जैसे कि मॉडल प्री- या पोस्ट-सेव या डिलीट)।
ये संकेत आपको तुरंत अपनी पसंद के कार्यों को करने की अनुमति देते हैं जो सिग्नल जारी होता है।
उदाहरण के लिए, जब भी कोई नया Django उपयोगकर्ता बनाया जाता है, तो उपयोगकर्ता मॉडल एक सिग्नल जारी करता है, जिसमें sender=User
जैसे sender=User
आपको विशेष रूप से होने वाली किसी विशिष्ट गतिविधि के संकेतों को सुनने की अनुमति देता है, इस मामले में, एक नया उपयोगकर्ता निर्माण ।
उपर्युक्त उदाहरण में, उपयोगकर्ता ऑब्जेक्ट बनाए जाने के तुरंत बाद एक UserProfile ऑब्जेक्ट को बनाने का इरादा है। इसलिए, विशेष रूप से User
मॉडल (डिफ़ॉल्ट Django उपयोगकर्ता मॉडल) से एक post_save
संकेत सुनने के बाद, हम एक नया User
बनाने के बाद एक UserProfile
ऑब्जेक्ट बनाते हैं।
Django दस्तावेज़ीकरण उपलब्ध सभी संभावित संकेतों पर व्यापक प्रलेखन प्रदान करता है ।
हालांकि, ऊपर दिए गए उदाहरण को व्यावहारिक रूप से एक विशिष्ट उपयोग के मामले में व्याख्या करना है जब सिग्नल का उपयोग करना एक उपयोगी जोड़ हो सकता है।
"महान शक्ति के साथ महान जिम्मेदारी आती है"। यह आपके पूरे ऐप या प्रोजेक्ट में बिखरे संकेतों को सिर्फ इसलिए ललचा सकता है क्योंकि वे कमाल के हैं। खैर, नहीं। क्योंकि वे शांत होते हैं, जो उनके दिमाग में आने वाली हर सरल स्थिति का समाधान नहीं है।
सिग्नल हमेशा की तरह महान हैं, सब कुछ नहीं। लॉगिन / लॉगआउट, सिग्नल महान हैं। प्रमुख मॉडल, यदि ठीक है, तो उपयोगकर्ता मॉडल की तरह संकेत जारी करता है।
आपके ऐप में प्रत्येक मॉडल के लिए सिग्नल बनाना एक बिंदु पर भारी हो सकता है, और Django सिग्नल के विरल उपयोग के पूरे विचार को पराजित कर सकता है।
जब ( Django पुस्तक के दो स्कूप पर आधारित) संकेतों का उपयोग न करें :
- संकेत एक विशेष मॉडल से संबंधित है और इसे उस मॉडल के तरीकों में से एक में ले जाया जा सकता है, जिसे संभवतः
save()
कहा जाता है। - सिग्नल को कस्टम मॉडल मैनेजर विधि से बदला जा सकता है।
- संकेत एक विशेष दृश्य से संबंधित है और इसे उस दृश्य में स्थानांतरित किया जा सकता है
जब संकेतों का उपयोग करना ठीक हो सकता है:
- आपके सिग्नल रिसीवर को एक से अधिक मॉडल में परिवर्तन करने की आवश्यकता है।
- आप एक ही सिग्नल को कई ऐप से भेजना चाहते हैं और उन्हें एक कॉमन रिसीवर द्वारा उसी तरह से हैंडल किया जाता है।
- आप मॉडल सहेजने के बाद कैश को अमान्य करना चाहते हैं।
- आपके पास एक असामान्य परिदृश्य है जिसे कॉलबैक की आवश्यकता है, और सिग्नल का उपयोग करने के अलावा इसे संभालने का कोई अन्य तरीका नहीं है। उदाहरण के लिए, आप तृतीय-पक्ष ऐप के मॉडल के
save()
याinit()
के आधार पर कुछ ट्रिगर करना चाहते हैं। आप तृतीय-पक्ष कोड को संशोधित नहीं कर सकते हैं और इसका विस्तार करना असंभव हो सकता है, इसलिए एक सिग्नल कॉलबैक के लिए ट्रिगर प्रदान करता है।
उपयोगकर्ता प्रोफ़ाइल उदाहरण का विस्तार
यह उदाहरण प्रो की तरह एक्सटेंडिंग Django यूजर प्रोफाइल से लिया गया एक स्निपेट है
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='user')
website = models.URLField(default='', blank=True)
bio = models.TextField(default='', blank=True)
def create_profile(sender, **kwargs):
user = kwargs["instance"]
if kwargs["created"]:
user_profile = UserProfile(user=user)
user_profile.save()
post_save.connect(create_profile, sender=User)
सिग्नल को पोस्ट / प्री करने के लिए अलग-अलग सिंटैक्स
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='user')
website = models.URLField(default='', blank=True)
bio = models.TextField(default='', blank=True)
@receiver(post_save, sender=UserProfile)
def post_save_user(sender, **kwargs):
user = kwargs.get('instance')
if kwargs.get('created'):
...
यह कैसे पता लगाएं कि क्या यह डालने या पूर्व_ सिग्नल में अपडेट है
pre_save
का उपयोग करके हम यह निर्धारित कर सकते हैं कि क्या हमारे डेटाबेस पर एक save
क्रिया किसी मौजूदा ऑब्जेक्ट को अपडेट करने या एक नया बनाने के बारे में थी।
इसे प्राप्त करने के लिए आप मॉडल ऑब्जेक्ट की स्थिति की जांच कर सकते हैं:
@receiver(pre_save, sender=User)
def pre_save_user(sender, instance, **kwargs):
if not instance._state.adding:
print ('this is an update')
else:
print ('this is an insert')
अब हर बार save
कार्रवाई जगह लेता है, pre_save
संकेत चलेंगे और प्रिंट होगा:
-
this is an update
अगर कार्रवाई एक अद्यतन कार्रवाई से ली गई है। -
this is an insert
यदि एक्शन इन्सर्ट एक्शन से निकला है।
ध्यान दें कि इस पद्धति के लिए अतिरिक्त डेटाबेस प्रश्नों की आवश्यकता नहीं है।
विस्तारित मॉडल पर इनहेरिटिंग सिग्नल
Django के संकेत पंजीकरण पर सटीक वर्ग हस्ताक्षर तक ही सीमित हैं, और इस तरह उप-वर्ग मॉडल तुरंत एक ही संकेत पर पंजीकृत नहीं हैं।
उदाहरण के लिए इस मॉडल और संकेत को लें
class Event(models.Model):
user = models.ForeignKey(User)
class StatusChange(Event):
...
class Comment(Event):
...
def send_activity_notification(sender, instance: Event, raw: bool, **kwargs):
"""
Fire a notification upon saving an event
"""
if not raw:
msg_factory = MessageFactory(instance.id)
msg_factory.on_activity(str(instance))
post_save.connect(send_activity_notification, Event)
विस्तारित मॉडल के साथ, आपको मैन्युअल रूप से प्रत्येक उपवर्ग पर संकेत संलग्न करना होगा अन्यथा वे प्रभावित नहीं होंगे।
post_save.connect(send_activity_notification, StatusChange)
post_save.connect(send_activity_notification, Comment)
पायथन 3.6 के साथ, आप इस बंधन को स्वचालित करने के लिए कक्षाओं में निर्मित कुछ अतिरिक्त वर्ग विधियों का लाभ उठा सकते हैं।
class Event(models.Model):
@classmethod
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
post_save.connect(send_activity_notification, cls)