Django管理模型保存 - 更新现有对象

时间:2011-09-20 14:18:46

标签: django django-models django-admin

这看起来很简单。

在我的模型save()上,我想基本上做get_or_create()。所以我想更新模型(如果存在)或创建一个新模型。

这似乎是一个非常简单的问题,但我说得不对劲!

class StockLevel(models.Model):
    stock_item = models.ForeignKey(StockItem)
    current_stock_level = models.IntegerField(blank=True, default=0)

    def save(self):
        try:
            # it exists
            a = StockLevel.objects.get(stock_item=self.stock_item)
            a.current_stock_level = self.current_stock_level
            a.save()

        except:
            # is does not exist yet
            # save as normaly would.
            super(StockLevel, self).save()

OR

def save(self):
    stock_level_item , created = StockLevel.objects.get_or_create(stock_item=self.stock_item)
    stock_level_item.current_stock_level = self.current_stock_level
    stock_level_item.save()

这也将进入无限循环。

这只会将save()置于无限循环中。但这是它应该如何运作的基本思路。

3 个答案:

答案 0 :(得分:5)

Django使用相同的 save()方法来创建和更新对象。 用户代码不需要确定是创建还是更新对象,因为这是由方法本身完成的。

此外,您可以使用方法可选参数强制 save()方法创建或更新对象。

Django docs

中介绍了这一点

答案 1 :(得分:1)

这听起来不是最好的方法。 save方法用于保存当前实例,而不是神奇地查询现有实例。您应该在表单或查看代码中处理此问题。

答案 2 :(得分:0)

所以这就是我昨天才解决的类似情况, 我创建了一个重复模型来存储更新的信息。

我们将新模型称为“ StockLevelUpdates”。

然后我使用信号从原始模型中插入保存的数据。

我将使用您上面的模型作为原始模型进行进一步说明。

class StockLevelUpdates(models.Model):
    stock_item = models.ForeignKey(StockItem)
    current_stock_level = models.IntegerField(blank=True, default=0)

@receiver(signals.post_save, sender=StockLevel)
def update_info(sender, instance, **kwargs):

    try:
        # if it exists
        a = StockLevelUpdates.objects.get(stock_item=instance.stock_item)
        a.current_stock_level = instance.current_stock_level
        a.save()

    except:
        # if it does not exist yet
        # save the new instance
        obj = StockLevelUpdates(stock_item=instance.stock_item,
                                current_stock_level = instance.current_stock_level)
        obj.save()  

这对我来说效果很好,您可以从重复模型中获取所有更新报告。

也许有更好的方法来做这种事情,但这是摆脱困境的一种快速方法。