Django models Django模型-如何思考

Django models Django模型-如何思考,django-models,django-admin,Django Models,Django Admin,伙计们 随着我的系统变得越来越复杂,我需要帮助思考如何实现复杂的行为。我会解释: 我有三种型号:采购、采购明细和库存 模型如下: class Purchase(models.Model): def __str__(self): return self.parceiro_pj.razao_social + ' em ' + str(self.data) + ": " + str(self.soma) parceiro_pj = models.ForeignKey

伙计们

随着我的系统变得越来越复杂,我需要帮助思考如何实现复杂的行为。我会解释:

我有三种型号:采购、采购明细和库存

模型如下:

class Purchase(models.Model):
    def __str__(self):
        return  self.parceiro_pj.razao_social + ' em ' + str(self.data) + ": " + str(self.soma)

    parceiro_pj = models.ForeignKey(ParceiroPJ,blank=True, null=True)
    createdat = models.DateTimeField()
    data = models.DateField(auto_now=True)
    soma = models.DecimalField(max_digits=10, decimal_places=2, default=0.00)

class PurchaseDetails(models.Model):

    def __str__(self):
        return str(self.parceiro_pj_insumo.insumo.nome) + ' - ' + str(self.quantidade) + ' - ' + str(self.createdat)

    purchase = models.ForeignKey(Purchase)
    parceiro_pj_insumo = models.ForeignKey(ParceiroPJInsumo)
    quantidade = models.IntegerField(blank=False, null=False)
    createdat = models.DateField(auto_now=True)

    def save(self, *args, **kwargs):
        super(PurchaseDetail, self).save(*args, **kwargs) # Call the "real" save() method.
        PurchaseDetail.objects.filter(Purchase=self.purchase.id).update(createdat=self.purchase.createdat.date())
        itens = PurchaseDetail.objects.filter(compra=self.purchase.id)
        valor = 0
        for item in itens:
            valor = valor + (item.parceiro_pj_insumo.preco * item.quantidade)

            no_estoque = Estoque.objects.get(insumo=item.parceiro_pj_insumo.insumo.id)
            unidade = Unidade.objects.get(nome=item.parceiro_pj_insumo.insumo.unidade.nome)
            qt = no_estoque.quantidade + item.quantidade
            volume_peso = no_estoque.volume_peso + (item.quantidade * item.parceiro_pj_insumo.insumo.volume_peso)
            Stock.objects.filter(insumo=item.parceiro_pj_insumo.insumo).update(quantidade=qt, unidade=unidade, volume_peso=volume_peso, updatedat=self.purchase.createdat.date())

        Purchase.objects.filter(pk=self.purchase.id).update(soma=valor)
        Purchase.objects.filter(pk=self.purchase.id).update(data=self.purchase.createdat.date())

class Stock(models.Model):

    def __str__(self):
        return str(self.insumo.nome) + '(' + str(self.insumo.marca.nome) +  ')' + ' - ' + str(self.quantidade)

    insumo = models.OneToOneField(Insumo)
    quantidade = models.IntegerField(blank=True, null=True)
    unidade = models.ForeignKey(Unidade, blank=True, null=True)
    volume_peso = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True) 
    updatedat = models.DateField(auto_now=False, blank=True, null=True)
有相关的: a) 一次购买有许多购买细节;b) 每个购买细节都会对库存产生影响。对于每个PurchaseDetail操作(插入、更改、删除),必须更新库存

我知道如何在每次插入PurchaseDetail时对库存进行更改。但对于删除和更新,逻辑似乎要复杂得多

如果我编辑PurchaseDetails,它的制作方式,如果我在数据库中已经有一个项目,当我保存PurchaseDetails时,它将再次计算(这个模型在admin的采购表单中进行了修改),导致错误并再次更新库存

我不知道如何实施正确的方法

我必须检查它是否是PurchaseDetail上的新项目,或者在更新库存之前它是否已经存在,我不知道怎么做。此外,我不知道hot tom在我必须删除PurchaseDetails并减少库存项目时会执行此案例


可以帮助任何人吗?

< P>你可以考虑探索Django信号所提供的功能,这将为你提供一个实现这种行为的好方法。信号可以通过内置的模型方法发送,如
\uuu init\uuu()
save()
,并且在应用程序的不同区域可能需要使用有关这些类型事件的信息时非常有用

Django的一些内置信号包括pre_save、post_save、pre_delete、post_delete等;定义和发送自己的信号也很简单

看一个你已经拥有的东西的简化示例,假设你想在每次出于某种原因保存相关的
PurchaseDetail
时更新特定的
Stock
。您可以定义如下方法:

def update_stock(sender, instance, **kwargs):
    purchase_details_id = instance.id
    # do something here, like update and save a stock

post_save.connect(update_stock, sender=PurchaseDetail)
update\u stock
是保存
PurchaseDetail
对象后将调用的接收器函数

供进一步参考:

谢谢你,韦斯!如果我在PurchaseDetails上执行预保存信号,您知道如何仅获取尚未保存的对象吗?在接收器函数中,您可能会根据PurchaseDetail sender键找到要更新的特定对象。我不清楚具体要做什么。您能否更清楚地说明如何区分已保存的新旧对象?@GustavoSooeiro好的,您可以检查self.pk以查看保存方法中的对象是否为新对象
如果self.pk为无:
如果对象为新对象,则为真