Django - 基于另一个字段更新模型字段

时间:2014-10-29 14:22:10

标签: python django orm model field

我是Django和Python的新手,我想做一些我以前经常在Java EE中做的事情。

考虑以下模型(仅限相关类):

class Item(models.Model):
    name = models.CharField(max_length=40)
    default_price = models.DecimalField(max_digits=6, decimal_places=2, default=50)

    def __unicode__(self):
        return self.name


class SaleDetail(models.Model):
    item = models.ForeignKey(Item)
    deposit = models.ForeignKey(Deposit)
    quantity = models.PositiveIntegerField()
    unit_price = models.DecimalField(max_digits=6, decimal_places=2)
    sale = models.ForeignKey(Sale)

    def item_updated(self, value):
        if self.unit_price == None:
            self.unit_price = value

我想要做的是,每次Item添加到SaleDetail时,如果SaleDetail.unit_price是新的{0},则Item.default_price更新为SaleDetail {已设置{1}}。

我以前在Java POJO中做的是将此逻辑包含在setter方法中。我已经尝试使用python属性来封装unit_price属性,但Django直接在引擎盖下更新字段,这样就会破坏一些自动功能。

我还尝试将ForeignKey子类化为接受回调函数,但我找不到在容器类上调用方法的方法。

我想这样做,所以我可以为UI提供默认值,但我不想在视图逻辑中包含此逻辑,因为从概念上讲,我认为这个逻辑应该在模型上(服务器端)< / p>

在这种情况下的其他用途是更新每个销售细节和销售的总数。我想在用户决定保存销售之前计算一下,因此保存信号不起作用。

谢谢!

2 个答案:

答案 0 :(得分:2)

看看这是否适合您。我们覆盖save方法并检查是否有pk。如果pk为无,我们知道SaleDetail是新的。然后,我们看看是否有unit_price。如果没有unit_price,我们会将其设置为Item.default_price

class Item(models.Model):
    name = models.CharField(max_length=40)
    default_price = models.DecimalField(max_digits=6, decimal_places=2, default=50)

    def __unicode__(self):
        return self.name


class SaleDetail(models.Model):
    item = models.ForeignKey(Item)
    deposit = models.ForeignKey(Deposit)
    quantity = models.PositiveIntegerField()
    unit_price = models.DecimalField(max_digits=6, decimal_places=2)
    sale = models.ForeignKey(Sale)

    def save(self, *args, **kwargs):
        # Make sure this is the first save (pk should be None) and there is no unit_price set
        if self.pk is None and not self.unit_price:
            self.unit_price = self.item.default_price
        elif not self.unit_price:
            self.unit_price = self.item.default_price

        # Call the original save method
        super(SaleDetail, self).save(*args, **kwargs)

答案 1 :(得分:1)

&#34;单价&#34;字面意思是两个不同领域的功能。因此我倾向于这样写:

class Item(models.Model):
    name = models.CharField(max_length=40)
    default_price = models.DecimalField(max_digits=6, decimal_places=2, default=50)

    def __unicode__(self):
        return self.name

class SaleDetail(models.Model):
    item = models.ForeignKey(Item)
    deposit = models.ForeignKey(Deposit)
    quantity = models.PositiveIntegerField()
    entered_unit_price = models.DecimalField(max_digits=6, decimal_places=2, default=None)
    sale = models.ForeignKey(Sale)

    @property
    def unit_price(self, value):
        if self.entered_unit_price is None:
            return self.item.default_price
        else:
            return self.entered_unit_price

    @unit_price.setter
    def unit_price(self, value):
        self.entered_unit_price = value

然后像这样使用它:

print(sd.unit_price)
sd.unit_price = 500 
sd.save()