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) #Cart object where TransactionDetail.cart= Cart.id
Cart.stock -= TransactionDetail.amount
이것을 달성하기 위해 신호를 정말로 사용하고 싶다면 여기에 간단한 방법이 있습니다.
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()
개인적으로 TransactionDetail의 save () 메서드를 재정의하고 거기에 새 TransactionDetail을 저장 한 다음 실행합니다.
self.product.stock -= self.amount
self.product.save()
를 피 하려면 신호 처리기 내에 저장하기 전에 신호 연결을 해제maximum recursion depth exceeded
해야 합니다. 위의 예 (Kenny Shen의 대답)는 다음과 같습니다.
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)
이것은 모델에 대한 신호 연결 해제 및 django 에서 다시 연결에 더 추상적이고 유용한 예제와 함께 자세히 설명되어 있습니다.
또한 django 문서의 https://docs.djangoproject.com/en/2.0/topics/signals/#disconnecting-signals 를 참조하십시오 .
사실, 설명하는 문서 Signals
는 다음과 django.dispatch.Signal.connect
같습니다.
def connect(self, receiver, sender=None, weak=True, dispatch_uid=None):
Connect receiver to sender for signal.
Arguments:
receiver
A function or an instance method which is to receive signals.
Receivers must be hashable objects.
If weak is True, then receiver must be weak referenceable.
Receivers must be able to accept keyword arguments.
If a receiver is connected with a dispatch_uid argument, it
will not be added if another receiver was already connected
with that dispatch_uid.
sender
The sender to which the receiver should respond. Must either be
a Python object, or None to receive events from any sender.
weak
Whether to use weak references to the receiver. By default, the
module will attempt to use weak references to the receiver
objects. If this parameter is false, then strong references will
be used.
dispatch_uid
An identifier used to uniquely identify a particular instance of
a receiver. This will usually be a string, though it may be
anything hashable.
참고 URL : https://stackoverflow.com/questions/13014411/django-post-save-signal-implementation
'Nice programing' 카테고리의 다른 글
git에서 서로 다른 디렉토리 계층을 가진 두 가지 분기를 병합하는 방법은 무엇입니까? (0) | 2020.11.29 |
---|---|
PHP에서 세션과 쿠키의 차이점은 무엇입니까? (0) | 2020.11.29 |
부울이 null인지 Java 확인 (0) | 2020.11.29 |
게시 요청에서 JAX-RS 클라이언트의 응답 본문 읽기 (0) | 2020.11.29 |
Swift : 제네릭 유형이 프로토콜을 준수하는지 확인 (0) | 2020.11.29 |