Правильный способ записи конфигурации сигнала Django post_save - PullRequest
0 голосов
/ 16 мая 2019

Я пытался научиться использовать сигналы, и, к сожалению, мой код ниже не работает.Кроме того, я натолкнулся на дюжину постов, в которых все показывают разные способы сделать это.

Моя цель в этом посте - прояснить и прийти к консенсусу в отношении написания сигналов наилучшим возможным способом в 2019 году длямасштабируемость.В этом примере используется post_save.

model.py

from django.db import models

from metrics.models import InventoryProduct
from product.models.product import Product


class PurchasedOrder(models.Model):
    __quantity_sold = None

    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    purchase_quantity = models.IntegerField()
    quantity_sold = models.IntegerField(default=0)

    def __init__(self, *args, **kwargs):
        super(PurchasedOrder, self).__init__(*args, **kwargs)
        self.__original_quantity_sold = self.quantity_sold

    def save(self, *args, **kwargs):
        # If the quantity sold field has changed run the update_sold_out method
        if self.quantity_sold != self.__original_quantity_sold:
            PurchasedOrderLogic.update_sold_out(self)

        super(PurchasedOrder, self).save(*args, **kwargs)
        self.__original_quantity_sold = self.quantity_sold

    def __str__(self):
        return self.product.name

signal.py:

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

from purchasing.models import PurchasedOrder
from purchasing.services.models_logic import PurchasedOrderLogic


@receiver(post_save, sender=PurchasedOrder)
def update_inventory_product_total_qty_purchased(sender, instance):
    PurchasedOrderLogic.update_inventory_product_total_qty_purchased(
        sender, instance.product.id, instance.purchase_quantity
    )

Здесь находится моя логика.Когда я обновляю поле Purchase_Order purchase_quantity, оно также должно обновлять поле total_qty_purchased InventoryProduct.

purchase.services.models_logic.py

class PurchasedOrderLogic(object):
    @static_method
    def update_inventory_product_total_qty_purchased(purchased_order_class, product_id):
        inventory_product = InventoryProduct.objects.get(pk=product_id)
        total_qty_purchased = purchased_order_class.objects.filter(product_id=product_id).aggregate(
            Sum('purchase_quantity')
        ).get('purchase_quantity__sum')

        inventory_product.total_qty_purchased = total_qty_purchased
        inventory_product.save()

apps.py

from django.apps import AppConfig
from django.db.models.signals import post_save
from django.utils.translation import ugettext_lazy as _

from purchasing.models import PurchasedOrder
from purchasing.signals import update_inventory_product_total_qty_purchased


class PurchasingConfig(AppConfig):
    name = 'purchasing'
    verbose_name = _('purchasing')

    def ready(self):
        post_save.connect(update_inventory_product_total_qty_purchased, sender=PurchasedOrder)

Чего не хватает?Я не уверен, даже если сигнал работает?

Я запускаю .save (), вручную изменяя любое поле в модели.

Лично я изменил поле purchase_quantity, которое должно печатать это значение, так как оно вызывается внутри метода update_inventory_product_total_qty_purchased

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...