2016-12-29 4 views
1

フェローズ、Djangoモデル - 考える方法

私のシステムは複雑になっているので、複雑な動作を実装する方法を考えるのに助けが必要です。私は説明します:

私は、購入、購入詳細、在庫の3つのモデルがあります。次のように

モデルは次のとおりです。

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)は1回の購入は、多くのPurchaseDetailsを持っています。 b)すべてのPurchaseDetailは株式に影響を与えます。すべてのPurchaseDetail操作(挿入、変更、削除)に対して、在庫を更新する必要があります。

PurchaseDetailを挿入するたびに在庫を変更する方法を理解しています。しかし、DELETEとUPDATEの場合、ロジックははるかに複雑に見えます。

PurchaseDetailsを編集すると、すでにデータベースにアイテムがある場合は、PurchaseDetailsを保存すると再び計算されます(このモデルは管理フォームに購入フォームが組み込まれています)。株式を再び更新する。

正しい方法を実装する方法はわかりません。

私はPurchaseDetailの新しい項目かどうか、または在庫が更新される前に既に存在する登録簿であるかどうかを確認する必要があります。また、HotDomeがPurchaseDetailsを削除して在庫を減らさなければならない場合、ホット・トムがその事件を実装するのを知らない。

誰でも手伝ってください。

答えて

1

Djangoシグナルによって提供される機能を調べることで、このような振る舞いを実装するうえで役立ちます。信号は、__init__()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_stockPurchaseDetailオブジェクトの保存後に呼び出されるレシーバ関数です。さらに参考のために

https://docs.djangoproject.com/en/1.10/ref/signals/

+0

はあなたにウェスをありがとう! PurchaseDetailsでpre_save信号を実装すると、まだ保存されていないオブジェクトのみをどのように取得できますか? –

+0

レシーバ機能では、PurchaseDetail送信者キーに基づいて具体的に更新するオブジェクトを見つけることができます。 –

+0

私は何をすべきかについて明確なイメージを持っていません。古いオブジェクトと新しいオブジェクトの違いを保存する方法をもっと明確にしてください。 –

関連する問題