4

我注意到在模型上调用 save() 后不能保证数据库会同步更新。

我通过对以下方法进行 ajax 调用做了一个简单的测试

def save(request, id)
  product = ProductModel.objects.find(id = id)
  product.name = 'New Product Name'
  product.save()

  return HTTPResponse('success')

在客户端,我等待上述方法的响应,然后执行 findAll 方法来检索产品列表。返回的产品列表包含更新产品名称的旧值。

但是,如果我延迟对产品列表的请求,那么它包含新值,就像它应该的那样。

这意味着如果在新值写入数据库之前触发,则返回 HTTPResponse('success') 。

如果上述情况属实,那么是否有办法仅在数据库更新后才返回 HTTP 响应。

4

2 回答 2

5

您应该更突出地提到 App Engine。我已将其添加到标签中。

这绝对是因为您对 GAE 缺乏了解,而不是与 Django 有任何关系。您应该阅读有关数据存储中最终一致性的 GAE 文档,并适当地构建模型和查询。

使用标准关系数据库运行的普通 Django 不会有这个问题。

于 2013-10-20T08:07:27.207 回答
1

在 .save() 函数结束其流程之前,视图不应返回任何内容。

至于流程本身,Django 的文档非常明确地声明它:

保存对象时,Django 执行以下步骤:

1)发出预保存信号。发送信号 django.db.models.signals.pre_save,允许任何侦听该信号的函数采取一些自定义操作。

2)预处理数据。要求对象上的每个字段执行该字段可能需要执行的任何自动数据修改。

大多数字段不进行预处理——字段数据保持原样。预处理仅用于具有特殊行为的字段。例如,如果您的模型具有 auto_now=True 的 DateField,则预保存阶段将更改对象中的数据以确保日期字段包含当前日期戳。(我们的文档还没有包含所有具有这种“特殊行为”的字段的列表。)

3)为数据库准备数据。要求每个字段以可以写入数据库的数据类型提供其当前值。

大多数字段不需要数据准备。简单的数据类型,例如整数和字符串,可以作为 Python 对象“准备写入”。但是,更复杂的数据类型通常需要一些修改。

例如,DateField 字段使用 Python 日期时间对象来存储数据。数据库不存储日期时间对象,因此必须将字段值转换为符合 ISO 标准的日期字符串才能插入数据库。

4)将数据插入数据库。然后将预处理、准备好的数据组合成一个 SQL 语句以插入数据库。

5)发出保存后信号。发送信号 django.db.models.signals.post_save,允许任何侦听该信号的函数采取一些自定义操作。

让我注意,如果您将@transaction.commit_on_success装饰器应用于您的视图,那么您收到的行为是可能的,但是,我在您的代码中看不到它。
更多关于交易:https ://docs.djangoproject.com/en/1.5/topics/db/transactions/

于 2013-10-20T07:33:20.857 回答