Django中使用refresh_from_db的正确方式是什么?

5
我正在使用Django 1.8,Mezzanine,Cartridge,并使用Postgresql作为数据库。我已经直接从数据库更新了num_in_stock。在数据库中所有数量都是正确的,但在我的网站上不正确。我知道解决方案在here,但我不知道该怎么做。我真的需要有人给我详细解释一下。你会如何在Cartridge中使用它来刷新num_in_stock?
3个回答

9
这是更新一个对象所需的全部步骤。将 object_name 替换为您的对象即可。
object_name.refresh_from_db()

9
我假设您正在使用F表达式
根据文档F表达式
使得可以引用模型字段值并对其执行数据库操作,而不必将它们从数据库中提取到Python内存中。
您直接在数据库中工作。Python不知道模型字段的值。没有任何东西存在于内存中,所有操作都在数据库上进行。
文档的示例:
from django.db.models import F

reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()

尽管reporter.stories_filed = F('stories_filed') + 1看起来像是将值赋给实例属性的普通Python赋值,但实际上它是描述对数据库执行操作的SQL构造。

因此,为了让Python知道这个值,您需要重新加载对象。

要访问以这种方式保存的新值,必须重新加载对象:

reporter = Reporters.objects.get(pk=reporter.pk)
# Or, more succinctly:
reporter.refresh_from_db()

在你的例子中:
object_name.refresh_from_db()

还有一件事...

F()分配在Model.save()之后仍然存在

将F()对象分配给模型字段后,它们会在保存模型实例后持续存在,并且将应用于每个save()。

reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()

reporter.name = 'Tintin Jr.'
reporter.save()

在这种情况下,stories_filed 将会更新两次。如果它最初是1,则最终值将为3。可以通过重新加载模型对象来避免这种持久性,例如使用refresh_from_db()

1
这应该是被接受的答案。其他答案没有解释为什么和何时需要使用refresh_from_db() - KlausCPH
我想知道这种行为是否会影响“TestCase”?我正在测试一个使用filter().update(F("balance") + amount)更新用户余额的方法,但是如果我在测试函数内执行refresh_from_db(),我只能得到旧值。而在方法本身内执行刷新(而不是在测试函数内),则可以获得预期的值并通过测试:\ - Salma Hassan

3

我假设num_in_stock是您的模型类的属性。如果是这样,您应该获取该类的实例(即object_name),然后使用下面的代码进行刷新:

object_name.refresh_from_db()

之后,您可以像这样访问它:

object_name.num_in_stock

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