如何在Postgres/Django中创建生成/计算列?

4
我该如何创建Postgres/DJANGO的生成/计算列?
我尝试了两种方式:
(1)通过类:
(2)通过数据库函数:
class Product(models.Model):
    name = models.CharField(max_length=200, null=True)
    precio_costo = models.FloatField(null=True)
    cantidad = models.IntegerField(null=True)
    monto_stock = models.FloatField(
        always_generated='precio_costo * cantidad', stored=True)

我收到的错误信息:

类型错误:init()收到了一个意外的关键字参数'always_generated'

(2) 直接通过POSTGRES管理员

但是我无法更新或添加新字段,Django需要默认值。


请解释一下...你在做什么?你遇到了什么问题?你尝试了哪些方法来解决这个问题? - Biplove Lamichhane
1
always_generated 似乎不是一个有效的东西。你为什么期望它能够工作呢? - Mad Wombat
2个回答

0

你真的需要将结果monto_stock存储在数据库中吗?

如果不需要,那么也许只需在类上使用Python方法/属性:

class Product(models.Model):
    name = models.CharField(max_length=200, null=True)
    precio_costo = models.FloatField(null=True)
    cantidad = models.IntegerField(null=True)

    @property
    def monto_stock(self):
        return self.precio_costo * self.cantidad

如果是的话,或许可以在模型的 save() 方法中计算结果:
class Product(models.Model):
    name = models.CharField(max_length=200, null=True)
    precio_costo = models.FloatField(null=True)
    cantidad = models.IntegerField(null=True)
    monto_stock = models.FloatField(null=True)

    def save(self, *args, **kwargs):
        self.monto_stock = self.precio_costo * self.cantidad
        super().save(*args, **kwargs)

请注意:您的字段允许为空,因此如果任何字段实际包含空值(因为在Python中无法进行NULL/None乘法),则会出现错误。

这些选项中有哪些适合您?


编辑:如果选择第一种选项,在视图中使用属性monto_stock,您可以像访问模型的任何其他属性一样简单地访问它(但只能进行读取操作)。例如:

# get a single product
p = Product.objects.first()
print(p.monto_stock)

# get sum of all products
print(sum(p.monto_stock for p in Product.objects.all()))

请注意,由于它是Python类属性而不是DB字段,因此不能直接以这种方式在数据库查询中使用。
# will NOT work
print(Product.objects.aggregate(Sum('monto_stock'))))

比如说,我不会将这些值存储在我的数据库中。如何在我的视图中访问“def monto_stock”的总和?提前感谢! - Isesy Miguel Ng

0
我在Django项目网站上也找到了一种总是生成的解决方案。 经过尝试了很多方法,最终有一种方法对我有效。
那就是从models.py中删除注释所有具有数据库触发器的列条目。
例如:自动递增列、当前时间戳列、生成列等。
# requesttimestamp = models.BigIntegerField(db_column='RequestTimeStamp', always_generated='createddate')  # Here I was getting that error.
# createddate = models.DateTimeField(db_column='CreatedDate', auto_now_add=True)

所以我评论了这两行代码,结果如预期。
创建实例保存记录时,也无需传递任何参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接