2012-10-22 34 views
44

Tôi có câu hỏi về django.Thực hiện tín hiệu Django post_save()

Tôi có ManyToMany Models đây

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) 

Đối với 1 giỏ đối tượng được tạo ra, tôi có thể chèn nhiều như đối tượng TransactionDetail mới (sản phẩm và số tiền). Câu hỏi của tôi là. Làm thế nào tôi có thể thực hiện kích hoạt? Những gì tôi muốn là bất cứ khi nào một chi tiết giao dịch được tạo ra, tôi muốn số lượng cổ phiếu của sản phẩm được trừ bằng số tiền trong transactiondetail.

Tôi đã đọc về post_save() nhưng tôi không chắc chắn cách triển khai. có lẽ một cái gì đó như thế này

khi: post_save (TransactionDetail, giỏ hàng) #Cart đối tượng nơi TransactionDetail.cart = Cart.id

Cart.stock -= TransactionDetail.amount 
+3

Bạn có khả năng chạy vào điều kiện cuộc đua nếu bạn làm theo cách đó. –

Trả lời

109

Nếu bạn thực sự muốn sử dụng tín hiệu để đạt được điều này, đây là một thời gian ngắn như thế nào,

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

ví dụ này là defiantly mất tích trong tài liệu django –

+1

THis là làm việc tốt cho tôi nhưng không biết tại sao nó là trong vòng lặp không biết chiều dài –

+3

Tôi nhận được 'tối đa đệ quy chiều sâu vượt quá' lỗi, bởi vì tôi đã lưu bản thân dụ trong '@ receiver' chức năng. Làm thế nào tôi có thể đạt được để cập nhật các mô hình tự? Tôi có phải ghi đè lên phương thức 'save()' của các mô hình không? – Dipak

10

Cá nhân tôi sẽ ghi đè phương pháp của TransactionDetail tiết kiệm() và trong đó tiết kiệm các TransactionDetail mới và sau đó chạy

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

Nếu bạn muốn tránh bị maximum recursion depth exceeded, thì bạn nên ngắt kết nối tín hiệu trước khi lưu trong bộ xử lý tín hiệu. Ví dụ trên (câu trả lời Kenny Shen của), sau đó sẽ là:

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) 

này được mô tả kỹ lưỡng trong Disconnect signals for models and reconnect in django, với một ví dụ trừu tượng và hữu ích hơn.

Xem thêm: https://docs.djangoproject.com/en/2.0/topics/signals/#disconnecting-signals trong tài liệu django.

Các vấn đề liên quan