2012-10-22 27 views
44

मेरे पास django के बारे में एक प्रश्न है।Django post_save() सिग्नल कार्यान्वयन

मैं ManyToMany यहाँ

class Product(models.Model): 
    name = models.CharField(max_length=255) 
    price = models.DecimalField(default=0.0, max_digits=9, decimal_places=2) 
    stock = models.IntegerField(default=0) 

    def __unicode__(self): 
     return self.name 

class Cart(models.Model): 
    customer = models.ForeignKey(Customer) 
    products = models.ManyToManyField(Product, through='TransactionDetail') 
    t_date = models.DateField(default=datetime.now()) 
    t_sum = models.FloatField(default=0.0) 

    def __unicode__(self): 
     return str(self.id) 

class TransactionDetail(models.Model): 
    product = models.ForeignKey(Product) 
    cart = models.ForeignKey(Cart) 
    amount = models.IntegerField(default=0) 

मॉडल बनाया 1 गाड़ी वस्तु के लिए है, मैं नए TransactionDetail वस्तु (उत्पाद और राशि) के रूप में कई सम्मिलित कर सकते हैं। मेरा सवाल यह है कि। मैं ट्रिगर को कैसे कार्यान्वित कर सकता हूं? जब भी एक लेनदेन विवरण बनाया जाता है, मैं चाहता हूं कि मैं चाहता हूं कि उत्पाद के शेयर की मात्रा लेनदेन की राशि से निकाली जाए।

मैंने post_save() के बारे में पढ़ा है लेकिन मुझे यकीन नहीं है कि इसे कैसे कार्यान्वित किया जाए। शायद इस

की तरह कुछ जब: post_save (TransactionDetail, कार्ट) वस्तु #Cart जहां TransactionDetail.cart = Cart.id

Cart.stock -= TransactionDetail.amount 
+3

यदि आप ऐसा करते हैं तो आप दौड़ की स्थिति में भागने की संभावना रखते हैं। –

उत्तर

109

चलाने तुम सच में इस लक्ष्य को हासिल करने के लिए संकेतों का उपयोग करना चाहते हैं, यहाँ, संक्षिप्त तरीका बताया गया है

from django.db.models.signals import post_save 
from django.dispatch import receiver 

class TransactionDetail(models.Model): 
    # ... fields here 

# method for updating 
@receiver(post_save, sender=TransactionDetail, dispatch_uid="update_stock_count") 
def update_stock(sender, instance, **kwargs): 
    instance.product.stock -= instance.amount 
    instance.product.save() 
+19

यह उदाहरण django दस्तावेज़ –

+1

में अपमानजनक रूप से गायब है, यह मेरे लिए ठीक काम कर रहा है लेकिन यह नहीं पता कि यह अज्ञात लंबाई –

+3

के लूप में क्यों है, मुझे 'अधिकतम रिकर्सन गहराई से अधिक' त्रुटि मिल रही है, क्योंकि मैं इंस्टेंस को स्वयं में सहेज रहा था '@ रिसीवर 'समारोह। मैं स्वयं मॉडल को अपडेट करने के लिए कैसे प्राप्त कर सकता हूं? क्या मुझे मॉडल की 'सेव()' विधि ओवरराइड करना है? – Dipak

10

व्यक्तिगत तौर पर मैं TransactionDetail के सेव() विधि ओवरराइड होगा और वहाँ में बचाने के नई TransactionDetail और फिर

self.product.stock -= self.amount 
self.product.save() 
1

आप maximum recursion depth exceeded हो रही से बचने के लिए चाहते हैं, तो आपको चाहिए डिस्कनेक्ट संकेत, संकेत हैंडलर भीतर सहेजने से पहले। उपरोक्त उदाहरण (केनी शेन का जवाब), तो होगा:

from django.db.models.signals import post_save 
from django.dispatch import receiver 

class TransactionDetail(models.Model): 
    # ... fields here 

# method for updating 
@receiver(post_save, sender=TransactionDetail, dispatch_uid="update_stock_count") 
def update_stock(sender, instance, **kwargs): 
instance.product.stock -= instance.amount 

post_save.disconnect(update_stock, sender=TransactionDetail) 
instance.product.save() 
post_save.connect(update_stock, sender=TransactionDetail) 

यह एक अधिक अमूर्त और उपयोगी उदाहरण के साथ Disconnect signals for models and reconnect in django में अच्छी तरह से वर्णन किया गया है,।

यह भी देखें: https://docs.djangoproject.com/en/2.0/topics/signals/#disconnecting-signals django दस्तावेज़ों में।