これを行うには、Djangoには「公式」メカニズムはありません。最近、Djangoフレームワークにいくつかの公式な解決策を追加する考え方が、django-developersメーリングリストのthis threadで議論されました。これは、あなたの場合に現在どのような解決策が最も良いかを示すインスピレーションとして役立つかもしれません。
この方法は、簡単な計算には適しています。値の計算にコストがかかる場合は、@cached_property
を使用すると、値を複数回使用すると少しでも役立ちます。
また、クエリーセットに注釈を追加することによって、これらの値を計算するデータベースに依存することもできます。これは、カスタム・マネージャーを定義する必要があります。これらはデフォルトのマネージャーを使用してretreivedしている場合
class InventoryManager(models.Manager):
def get_queryset(self):
super().get_queryset().annotate(total=F('stock_in') + F('balance'))
class Inventory(models.Model):
date = models.DateField(("Date"), default=datetime.now)
product = models.ForeignKey(Product)
stock_in = models.IntegerField()
stock_out = models.IntegerField()
balance = models.IntegerField()
particulars = models.CharField(max_length=250)
objects = InventoryManager()
これはあなたのInventory
モデルインスタンスにbalance
属性を追加します。
このアプローチ(リンクされたdjango-developersスレッドで説明したような)の問題は、モーダルがローカルで変更されたときの期待です。例えば
、私はモーダルのためstock_in
を変更した場合に代わりにカスタム・マネージャと、total
の値はまだデータベースからそれを取り出す時のstock_in
の値に対して有効になります:
あなたのクラスに
__getattr__
メソッドを追加する
>> inventory = Inventory(stock_in=20, balance=10)
>> inventory.total
AttributeError: 'Inventory' object has no attribute 'total'
をbかもしれません:
>> qs = Inventory.objects.filter(date__gte=date(2017, 12, 22))
>> inventory0 = qs[0]
>> print(inventory0.total, inventory0.stock_in, inventory.balance)
100, 50, 50
>> inventory.balance = 100
>> print(inventory0.total, inventory0.stock_in, inventory.balance)
100, 50, 100
また、全てのDBから取り出されていないモデルのインスタンスは文句を言わないtotal
属性を持っていますこのユースケースへの解決策ではありますが、依然としてローカル変更に伴う誤った回答が発生します。
'balance'は現在の株式を、' stock_in [out | out] 'は着信アイテムと発信アイテムの合計を表示しますか?そのような: 'バランス== initial_balance + stock_in - 在庫_out'ですか? – schwobaseggl