【问题标题】:Django - default field value depends on other field valueDjango - 默认字段值取决于其他字段值
【发布时间】:2016-12-28 05:04:06
【问题描述】:


我在设置默认字段值时遇到问题。我想做什么?
我希望 Packages 类中的价格是 Bill 类中 priceNoTax 的默认值。如您所见,所有三个类都是 逻辑连接。
示例:帐户 1 有一个 id 为 1 的包。此包的价格为 100。帐户 1 的 priceNoTax 默认值为 100。

如何做到这一点?我对此比较陌生,所以我需要帮助。

models.py

class Packages(models.Model):
     #other fields
     price = models.IntegerField(validators=[MinValueValidator(1)], verbose_name="Price of package")

class Account(models.Model):
     startDate = models.DateField(verbose_name="Start date")
     finishDate = models.DateField(verbose_name="Finish date")
     idPackage = models.ForeignKey(Packages, on_delete=models.CASCADE, verbose_name="Package")

class Bill(models.Model):
     date = models.DateField(default=datetime.now())
     tax = models.FloatField(default=0.20)
     priceNoTax = models.IntegerField()
     priceTax = models.FloatField(default=priceNoTax+(priceNoTax*tax))
     idAccount = models.ForeignKey(Account, on_delete=models.CASCADE, verbose_name="Account")

     def __str__(self):
         return self.date

非常感谢!!!

【问题讨论】:

  • 如何将信息输入模型?您是在使用管理页面还是从其他位置传递它?我可以想到几种方法来做到这一点,但没有一种专门将默认属性设置为另一个模型的值。
  • 我不需要 priceNoTaxpriceTax 字段,因为它们逻辑上已经连接。如果您想以Bill.objects.filter(idAccount__idPackage__price) 访问价格,您可以从Bill 类中查询。减少重复变量。

标签: python django default-value


【解决方案1】:

@kichik 回答了如何使用模板标签显示默认值,我建议通过 javascript 实现自动计算。

当然,您必须验证用户输入或实现@Chris Curvey 所说的save() 方法。

【讨论】:

【解决方案2】:

为什么需要它作为一个字段?您是否看到有人想要更改总价格而不将价格和税款更改为相应值的原因?如果它真的不需要是一个字段,你可以把它变成一个方法。

class Bill(models.Model):
     date = models.DateField(default=datetime.now())
     tax = models.FloatField(default=0.20)
     priceNoTax = models.IntegerField()
     idAccount = models.ForeignKey(Account, on_delete=models.CASCADE, verbose_name="Account")

     def priceTax(self):
       return self.priceNoTax + (self.priceNoTax*self.tax)

     def __str__(self):
         return self.date

您仍然可以在带有{{ bill.priceTax }} 的模板中以相同的方式使用它。在代码中,您需要使用bill.priceTax()

这样,无论含税价格或不含税价格如何变化,含税价格都应保持最新。

您还可以使用@property 装饰器来避免在代码中将其作为函数调用。

@property
def priceTax(self):
   return self.priceNoTax + (self.priceNoTax*self.tax)

更多信息请见https://docs.djangoproject.com/en/2.0/topics/db/models/#model-methods

【讨论】:

  • 10 年后... 这种方法的一个问题是使用 models.F() 表达式无法访问 priceTax
  • 如果您对此感到担心,可以将其添加到查询集stackoverflow.com/a/42491803/492773。这仍然不需要更改数据库,因此无需进行大规模迁移,10 年后也不会出现大问题。
  • 对“10 年后”感到抱歉...我不知道我是怎么做到的,但似乎我只是误读了日期...确实,那时没有超过 2 岁时间?...即使考虑到时间的流逝,这比我们想象的要快.. 已经有 6 年了.. 写到这里,新年快乐!
【解决方案3】:

也许将它添加到您的 Bill 类中?

def save(self, *args, **kwargs):
    if self.priceNoTax is None:
        self.priceNoTax = self.idAccount.idPackage.price
    super(Bill, self).save(*args, **kwargs)

【讨论】:

  • 这是为了保存,不是为了有默认值
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 2021-07-08
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 2019-03-28
  • 1970-01-01
相关资源
最近更新 更多