3

モデルに動的フィールドを作成するにはどうすればよいですか?

株式市場に関連するアプリケーションを書いているとしましょう。ある日に購入し、後日、今日の価格に基づいて利益 (または損失) を確認したいと考えています。私は次のようなモデルを持っています:

class Purchase(models.Model):
  ticker = models.CharField(max_length=5)
  date = models.DateField()
  price = models.DecimalField(max_digits=20, decimal_places=3)
  quantity = models.IntegerField()

私がやりたいのは、次のようなモデルを定義することです:

class PurchaseGain(Purchase):
  gain = models.DecimalField(max_digits=20, decimal_places=3)
  class Meta:
    proxy = True

私がこれを行うことができるように:

todays_price = get_price_from_webservice(ticker)
for p in PurchaseGain.objects.get_purchase_gain(todays_price):
  print '%s bought on %s for a gain of %s' % (p.ticker, p.date, p.gain)

p.gain は、get_purchase_gain への入力に基づいて動的に計算されます。その場で辞書を作成するだけでなく、モデルを使用したいと考えています。これは、これを渡してフォームを生成したり、インスタンスから変更を保存したりしたいからです。

派生した QuerySet を作成しようとしましたが、循環依存関係が発生しました。これは、Purchase が (カスタム マネージャーを介して) QuerySet について知る必要があり、QuerySet が、Purchase から派生した PurchaseGain をインスタンス化するために必要な反復子を返したためです。

どのようなオプションがありますか?

ありがとう、クレイグ

4

2 に答える 2

2

プロキシクラスを作成することは、私を混乱させました。Purchase に属性を追加するだけで、私が望んでいたことを達成することができました。

class PurchaseQuerySet(QuerySet):
  def __init__(self, *args, **kwargs):
    super(PurchaseQuerySet, self).__init__(*args, **kwargs)
    self.todays_price = None

  def get_with_todays_price(self, todays_price):
    self.todays_price = todays_price
    cloned = self.all()
    cloned.todays_price = todays_price
    return cloned

  def iterator(self):
    for p in super(PurchaseQuerySet, self).iterator():
      p.todays_price = self.todays_price
      yield p

class PurchaseManager(models.Manager):
  def get_query_set(self):
    return PurchaseQuerySet(self.model)

  def __getattr__(self, name)
    return getattr(self.get_query_set(), name)

class Purchase(models.Model):
  ticker = models.CharField(max_length=5)
  date = models.DateField()
  price = models.DecimalField(max_digits=20, decimal_places=3)
  quantity = models.IntegerField()

  objects = PurchaseManager()

  @property
  def gain(self):
    return self.todays_price - self.price

今私はできる:

for p in Purchase.objects.filter(ticker=ticker).get_with_todays_price(100):
  print p
  print p.gain
于 2012-06-02T18:18:44.320 に答える
2

モデルにgain()メソッドを追加してみませんか?

class Purchase(models.Model):
    ticker = models.CharField(max_length=5)
    date = models.DateField()
    price = models.DecimalField(max_digits=20, decimal_places=3)
    quantity = models.IntegerField()

    def gain(self, todays_price=None):
        if not todays_price:
            todays_price = get_price_from_webservice(self.ticker)
        result_gain = todays_price - self.price
        return result_gain

次に、あなたが望むことをほとんど行うことができます:

for p in Purchase.objects.all():
    print '%s bought on %s for a gain of %s' % (p.ticker, p.date, p.gain())
于 2012-05-31T07:24:54.610 に答える