首页 > 解决方案 > 从模型中更改或删除主键(实例)后如何保持相同的数据

问题描述

我希望保留与之前、更改或删除提供外键的模型之前保存的数据相同的数据,

我尝试过了

on_delete=models.SET_NULL

但仍然删除了我之前保存的实例

class Product(models.Model):
    product_name = models.CharField(unique=True, max_length=50 , 
    blank=False,null=False)
    price = models.PositiveIntegerField()
    active = models.BooleanField(default=True)

    def __str__(self):
        return self.product_name


class Order(models.Model):
    id = models.AutoField(primary_key = True)
    products = models.ManyToManyField(Product ,through='ProductOrder')
    date_time = models.DateTimeField(default=datetime.now()) 


    @property
    def total(self):
        return self.productorder_set.aggregate(
            price_sum=Sum(F('quantity') * F('product__price'), 
            output_field=IntegerField()) )['price_sum'] 


class ProductOrder(models.Model):
    product = models.ForeignKey(Product, on_delete=models.SET_NULL , null=True)
    ordering = models.ForeignKey(Order, on_delete=models.SET_NULL,blank=True,null=True ,default='')
    quantity = models.PositiveIntegerField(default=1)

    def __str__(self):
        return f"{self.product} : {self.quantity}"

以及如何将总价格保存在变量中,如果产品中的价格更新,它仍然是第一次?

以及如何防止从产品模型中删除产品后从订单模型中丢失数据感谢您的建议

标签: pythondjangomodel

解决方案


有多种方法可以解决这个问题,但通常与 Django 本身关系不大,因为这些是业务决策:

  1. 不要链接到ProductOrderProductOrder)模型中,而是直接将产品信息保存在ProductOrder模型中。例如,您可以使用 a JSONField(如果您在 PostgreSQL 上)并保留所有产品详细信息,包括价格。

  2. Product订购一次后不要更改。即,您可以使更改/删除Product( on_delete=models.PROTECT) 成为不可能。提供Product唯一的 SKU 和版本号,Product在价格变化时创建您的新版本。这样,所有订单都将使用对Product实际订购的参考。获取Products可以购买的内容时,请始终获取最新版本的Product. 您可以为此创建一个新ProductVersion表并链接到该表而不是Product.

  3. 不允许删除Product( on_delete=PROTECT),但允许更改价格。请注意,如果其他特性发生Product变化(例如颜色),您应该始终创建一个新的Product. 保留一份已付价格的副本ProductOrder(订单的行项目)。这是最常见的方法。您只需复制行项目中的价格,以便始终获得客户支付的实际价格。

您选择的解决方案在一定程度上取决于您公司的业务需求,即产品的管理方式、需要保留的内容等……这还取决于您希望客户在查找他们的历史记录时能够看到的内容订单。


推荐阅读