向Django模型添加动态字段

2024-10-02 08:26:33 发布

您现在位置:Python中文网/ 问答频道 /正文

如何在模型上创建动态场?在

假设我正在写一个与股票市场相关的应用程序。我是在某天买的,以后某个时候我想根据今天的价格来计算盈亏。我会有一个这样的模型:

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()

我想做的是定义一个类似这样的模型:

^{pr2}$

所以我可以这样做:

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是根据输入动态计算的,以获得“购买增益”。我希望使用一个模型,而不仅仅是动态地构建字典,因为我希望传递这个模型,并从实例中生成表单、保存更改等。在

我尝试创建一个派生的QuerySet,但是这导致了循环依赖,因为Purchase需要知道QuerySet(通过定制管理器),QuerySet返回了一个迭代器,需要实例化PurchaseGain,它是从PurchaseGain派生的。在

我有什么选择?在

谢谢, 克雷格


Tags: 实例模型forgetdatemodels动态purchase
2条回答

创建一个代理类让我很困惑。通过在购买中添加属性,我就可以完成我想要的。在

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

现在我可以:

^{pr2}$

为什么不在模型中添加一个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

然后你就可以随心所欲了:

^{pr2}$

相关问题 更多 >

    热门问题